-
-
Notifications
You must be signed in to change notification settings - Fork 6
Release/3.0.3 #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Release/3.0.3 #98
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,77 @@ | ||
| package com.frogobox.appcompose | ||
|
|
||
| import androidx.compose.foundation.layout.Box | ||
| import androidx.compose.foundation.layout.Arrangement | ||
| import androidx.compose.foundation.layout.Column | ||
| import androidx.compose.foundation.layout.Spacer | ||
| import androidx.compose.foundation.layout.fillMaxSize | ||
| import androidx.compose.foundation.layout.fillMaxWidth | ||
| import androidx.compose.foundation.layout.height | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.material3.Button | ||
| import androidx.compose.material3.MaterialTheme | ||
| import androidx.compose.material3.Scaffold | ||
| import androidx.compose.material3.Text | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.ui.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.graphics.Color | ||
| import androidx.compose.ui.unit.dp | ||
| import com.frogobox.compose.view.FrogoComposeActivity | ||
| import com.frogobox.sdk.ext.startActivityExt | ||
|
|
||
| class MainComposeActivity : FrogoComposeActivity() { | ||
|
|
||
| @Composable | ||
| override fun SetupCompose() { | ||
| Box( | ||
| modifier = Modifier.Companion.fillMaxSize(), | ||
| contentAlignment = Alignment.Companion.Center | ||
| ) { | ||
| Text( | ||
| color = Color.Companion.White, | ||
| text = "Hello from Frogo Compose!" | ||
| ) | ||
| Scaffold { padding -> | ||
| Column( | ||
| modifier = Modifier | ||
| .fillMaxSize() | ||
| .padding(padding) | ||
| .padding(24.dp), | ||
| verticalArrangement = Arrangement.Center, | ||
| horizontalAlignment = Alignment.CenterHorizontally | ||
| ) { | ||
| Text( | ||
| text = "Frogo Compose Samples", | ||
| style = MaterialTheme.typography.headlineMedium | ||
| ) | ||
|
|
||
| Spacer(modifier = Modifier.height(32.dp)) | ||
|
|
||
| // Sample 1: Single Activity Compose (this class itself demonstrates FrogoComposeActivity) | ||
| Button( | ||
| modifier = Modifier.fillMaxWidth(), | ||
| onClick = { | ||
| startActivityExt<SampleNavComposeActivity> {} | ||
| } | ||
| ) { | ||
| Text("Navigation Compose (NavHost)") | ||
| } | ||
|
|
||
| Spacer(modifier = Modifier.height(16.dp)) | ||
|
|
||
| // Sample 2: Fragment Compose hosted in an Activity | ||
| Button( | ||
| modifier = Modifier.fillMaxWidth(), | ||
| onClick = { | ||
| startActivityExt<SampleFragmentComposeActivity> {} | ||
| } | ||
| ) { | ||
| Text("Fragment Compose (SampleFragment)") | ||
| } | ||
|
|
||
| Spacer(modifier = Modifier.height(16.dp)) | ||
|
|
||
| // Sample 3: Bottom Sheet Fragment Compose (shown as dialog) | ||
| Button( | ||
| modifier = Modifier.fillMaxWidth(), | ||
| onClick = { | ||
| SampleBottomSheetFragment().show(supportFragmentManager, "bottom_sheet") | ||
| } | ||
| ) { | ||
| Text("Bottom Sheet Fragment Compose") | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| package com.frogobox.appcompose | ||
|
|
||
| import android.widget.Toast | ||
| import androidx.compose.foundation.background | ||
| import androidx.compose.foundation.layout.Column | ||
| import androidx.compose.foundation.layout.Spacer | ||
| import androidx.compose.foundation.layout.fillMaxWidth | ||
| import androidx.compose.foundation.layout.height | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.foundation.shape.RoundedCornerShape | ||
| import androidx.compose.material3.Button | ||
| import androidx.compose.material3.MaterialTheme | ||
| import androidx.compose.material3.Text | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.ui.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.unit.dp | ||
| import com.frogobox.compose.view.FrogoComposeBottomSheetFragment | ||
|
|
||
| class SampleBottomSheetFragment : FrogoComposeBottomSheetFragment() { | ||
|
|
||
| @Composable | ||
| override fun setupCompose() { | ||
| Column( | ||
| modifier = Modifier | ||
| .fillMaxWidth() | ||
| .background( | ||
| color = MaterialTheme.colorScheme.surface, | ||
| shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp) | ||
| ) | ||
| .padding(24.dp), | ||
| horizontalAlignment = Alignment.CenterHorizontally | ||
| ) { | ||
| Text( | ||
| text = "Sample Bottom Sheet Fragment", | ||
| style = MaterialTheme.typography.titleLarge, | ||
| color = MaterialTheme.colorScheme.onSurface | ||
| ) | ||
| Spacer(modifier = Modifier.height(8.dp)) | ||
| Text( | ||
| text = "This bottom sheet UI is built entirely using Jetpack Compose hosted inside a BottomSheetDialogFragment.", | ||
| style = MaterialTheme.typography.bodyMedium, | ||
| color = MaterialTheme.colorScheme.onSurfaceVariant | ||
| ) | ||
| Spacer(modifier = Modifier.height(16.dp)) | ||
| Button(onClick = { | ||
| Toast.makeText(context, "Action from Bottom Sheet!", Toast.LENGTH_SHORT).show() | ||
| dismiss() | ||
| }) { | ||
| Text("Dismiss Sheet") | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package com.frogobox.appcompose | ||
|
|
||
| import android.widget.Toast | ||
| import androidx.compose.foundation.layout.Arrangement | ||
| import androidx.compose.foundation.layout.Column | ||
| import androidx.compose.foundation.layout.Spacer | ||
| import androidx.compose.foundation.layout.fillMaxSize | ||
| import androidx.compose.foundation.layout.height | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.material3.Button | ||
| import androidx.compose.material3.MaterialTheme | ||
| import androidx.compose.material3.Text | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.runtime.collectAsState | ||
| import androidx.compose.runtime.getValue | ||
| import androidx.compose.ui.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.unit.dp | ||
| import androidx.lifecycle.viewmodel.compose.viewModel | ||
| import com.frogobox.compose.view.FrogoComposeFragment | ||
|
|
||
| class SampleFragment : FrogoComposeFragment() { | ||
|
|
||
| private lateinit var sampleViewModel: SampleViewModel | ||
|
|
||
| override fun setupViewModel() { | ||
| super.setupViewModel() | ||
| sampleViewModel = SampleViewModel() | ||
| } | ||
|
Comment on lines
+24
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
|
||
| @Composable | ||
| override fun setupCompose() { | ||
| val vm: SampleViewModel = viewModel() | ||
| val state by vm.uiState.collectAsState() | ||
|
|
||
| Column( | ||
| modifier = Modifier | ||
| .fillMaxSize() | ||
| .padding(16.dp), | ||
| verticalArrangement = Arrangement.Center, | ||
| horizontalAlignment = Alignment.CenterHorizontally | ||
| ) { | ||
| Text(text = "Sample Fragment Compose", style = MaterialTheme.typography.headlineMedium) | ||
| Spacer(modifier = Modifier.height(8.dp)) | ||
| Text(text = state.description, style = MaterialTheme.typography.bodyMedium) | ||
| Spacer(modifier = Modifier.height(16.dp)) | ||
| Text(text = "Counter: ${state.counter}", style = MaterialTheme.typography.titleLarge) | ||
| Spacer(modifier = Modifier.height(16.dp)) | ||
| Button(onClick = { | ||
| vm.incrementCounter() | ||
| Toast.makeText(context, "Clicked from Compose Fragment!", Toast.LENGTH_SHORT).show() | ||
| }) { | ||
| Text("Increment Counter") | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+31
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In Jetpack Compose, the idiomatic way to obtain the Android @Composable
override fun setupCompose() {
val vm: SampleViewModel = viewModel()
val state by vm.uiState.collectAsState()
val context = androidx.compose.ui.platform.LocalContext.current
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Sample Fragment Compose", style = MaterialTheme.typography.headlineMedium)
Spacer(modifier = Modifier.height(8.dp))
Text(text = state.description, style = MaterialTheme.typography.bodyMedium)
Spacer(modifier = Modifier.height(16.dp))
Text(text = "Counter: ${state.counter}", style = MaterialTheme.typography.titleLarge)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = {
vm.incrementCounter()
Toast.makeText(context, "Clicked from Compose Fragment!", Toast.LENGTH_SHORT).show()
}) {
Text("Increment Counter")
}
}
} |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.frogobox.appcompose | ||
|
|
||
| import android.os.Bundle | ||
| import androidx.appcompat.app.AppCompatActivity | ||
|
|
||
| /** | ||
| * Host Activity for SampleFragment (Compose-based Fragment). | ||
| * Demonstrates hosting a FrogoComposeFragment inside an Activity. | ||
| */ | ||
| class SampleFragmentComposeActivity : AppCompatActivity() { | ||
|
|
||
| override fun onCreate(savedInstanceState: Bundle?) { | ||
| super.onCreate(savedInstanceState) | ||
| if (savedInstanceState == null) { | ||
| supportFragmentManager.beginTransaction() | ||
| .replace(android.R.id.content, SampleFragment()) | ||
| .commit() | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,92 @@ | ||||||||||||||||||||||||||||
| package com.frogobox.appcompose | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import android.os.Bundle | ||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Arrangement | ||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Column | ||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Spacer | ||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.fillMaxSize | ||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.height | ||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.padding | ||||||||||||||||||||||||||||
| import androidx.compose.material3.Button | ||||||||||||||||||||||||||||
| import androidx.compose.material3.MaterialTheme | ||||||||||||||||||||||||||||
| import androidx.compose.material3.Scaffold | ||||||||||||||||||||||||||||
| import androidx.compose.material3.Text | ||||||||||||||||||||||||||||
| import androidx.compose.runtime.Composable | ||||||||||||||||||||||||||||
| import androidx.compose.ui.Alignment | ||||||||||||||||||||||||||||
| import androidx.compose.ui.Modifier | ||||||||||||||||||||||||||||
| import androidx.compose.ui.unit.dp | ||||||||||||||||||||||||||||
| import androidx.navigation.NavHostController | ||||||||||||||||||||||||||||
| import androidx.navigation.compose.NavHost | ||||||||||||||||||||||||||||
| import androidx.navigation.compose.composable | ||||||||||||||||||||||||||||
| import com.frogobox.compose.view.FrogoComposeNavActivity | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| class SampleNavComposeActivity : FrogoComposeNavActivity() { | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| override fun onCreateExt(savedInstanceState: Bundle?) { | ||||||||||||||||||||||||||||
| super.onCreateExt(savedInstanceState) | ||||||||||||||||||||||||||||
| // Additional configuration during onCreate if needed | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||
| override fun SetupNavigation(navController: NavHostController) { | ||||||||||||||||||||||||||||
|
Comment on lines
+23
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||||||||||||||||
| NavHost(navController = navController, startDestination = "first") { | ||||||||||||||||||||||||||||
| composable("first") { | ||||||||||||||||||||||||||||
| FirstScreen( | ||||||||||||||||||||||||||||
| onNavigateToSecond = { navController.navigate("second") }, | ||||||||||||||||||||||||||||
| onShowBottomSheet = { | ||||||||||||||||||||||||||||
| SampleBottomSheetFragment().show(supportFragmentManager, "bottom_sheet") | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| composable("second") { | ||||||||||||||||||||||||||||
| SecondScreen( | ||||||||||||||||||||||||||||
| onBack = { navController.popBackStack() } | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||
| private fun FirstScreen(onNavigateToSecond: () -> Unit, onShowBottomSheet: () -> Unit) { | ||||||||||||||||||||||||||||
| Scaffold { padding -> | ||||||||||||||||||||||||||||
| Column( | ||||||||||||||||||||||||||||
| modifier = Modifier | ||||||||||||||||||||||||||||
| .fillMaxSize() | ||||||||||||||||||||||||||||
| .padding(padding) | ||||||||||||||||||||||||||||
| .padding(16.dp), | ||||||||||||||||||||||||||||
| verticalArrangement = Arrangement.Center, | ||||||||||||||||||||||||||||
| horizontalAlignment = Alignment.CenterHorizontally | ||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||
| Text(text = "First Screen (Navigation Compose)", style = MaterialTheme.typography.headlineMedium) | ||||||||||||||||||||||||||||
| Spacer(modifier = Modifier.height(16.dp)) | ||||||||||||||||||||||||||||
| Button(onClick = onNavigateToSecond) { | ||||||||||||||||||||||||||||
| Text("Go to Second Screen") | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| Spacer(modifier = Modifier.height(16.dp)) | ||||||||||||||||||||||||||||
| Button(onClick = onShowBottomSheet) { | ||||||||||||||||||||||||||||
| Text("Open Bottom Sheet Dialog") | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||
| private fun SecondScreen(onBack: () -> Unit) { | ||||||||||||||||||||||||||||
| Scaffold { padding -> | ||||||||||||||||||||||||||||
| Column( | ||||||||||||||||||||||||||||
| modifier = Modifier | ||||||||||||||||||||||||||||
| .fillMaxSize() | ||||||||||||||||||||||||||||
| .padding(padding) | ||||||||||||||||||||||||||||
| .padding(16.dp), | ||||||||||||||||||||||||||||
| verticalArrangement = Arrangement.Center, | ||||||||||||||||||||||||||||
| horizontalAlignment = Alignment.CenterHorizontally | ||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||
| Text(text = "Second Screen (Navigation Compose)", style = MaterialTheme.typography.headlineMedium) | ||||||||||||||||||||||||||||
| Spacer(modifier = Modifier.height(16.dp)) | ||||||||||||||||||||||||||||
| Button(onClick = onBack) { | ||||||||||||||||||||||||||||
| Text("Go Back") | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package com.frogobox.appcompose | ||
|
|
||
| import com.frogobox.compose.view.FrogoComposeStateViewModel | ||
|
|
||
| data class SampleUiState( | ||
| val title: String = "Frogo SDK Compose Sample", | ||
| val description: String = "This is a demonstration of UDF UI state.", | ||
| val counter: Int = 0 | ||
| ) | ||
|
|
||
| sealed interface SampleUiEffect { | ||
| data class ShowToast(val message: String) : SampleUiEffect | ||
| } | ||
|
|
||
| class SampleViewModel : FrogoComposeStateViewModel<SampleUiState, SampleUiEffect>(SampleUiState()) { | ||
|
|
||
| fun incrementCounter() { | ||
| updateState { | ||
| copy(counter = counter + 1) | ||
| } | ||
| emitEffect(SampleUiEffect.ShowToast("Counter incremented to ${currentState.counter}")) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the Fragment's nullable
contextproperty directly inside a Composable is discouraged. Instead, useLocalContext.currentto safely retrieve the non-nullContextassociated with the composition tree.@Composable override fun setupCompose() { val context = androidx.compose.ui.platform.LocalContext.current Column( modifier = Modifier .fillMaxWidth() .background( color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp) ) .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "Sample Bottom Sheet Fragment", style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onSurface ) Spacer(modifier = Modifier.height(8.dp)) Text( text = "This bottom sheet UI is built entirely using Jetpack Compose hosted inside a BottomSheetDialogFragment.", style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant ) Spacer(modifier = Modifier.height(16.dp)) Button(onClick = { Toast.makeText(context, "Action from Bottom Sheet!", Toast.LENGTH_SHORT).show() dismiss() }) { Text("Dismiss Sheet") } } }