### Display Alert Dialog Example Source: https://developer.android.com/develop/ui/compose/quick-guides/content/display-user-input Show how to display an alert dialog by managing its visibility state. This example demonstrates passing necessary parameters to the AlertDialog composable. ```kotlin @Composable fun DialogExamples() { // ... val openAlertDialog = remember { mutableStateOf(false) } // ... when { // ... openAlertDialog.value -> { AlertDialogExample( onDismissRequest = { openAlertDialog.value = false }, onConfirmation = { openAlertDialog.value = false println("Confirmation registered") // Add logic here to handle confirmation. }, dialogTitle = "Alert dialog example", dialogText = "This is an example of an alert dialog with buttons.", icon = Icons.Default.Info ) } } } } ``` -------------------------------- ### Full Scaffold Implementation Example Source: https://developer.android.com/develop/ui/compose/quick-guides/content/create-scaffold This example shows a complete Scaffold implementation with a top app bar, bottom app bar, and a floating action button. It demonstrates how to manage the button's click count and display it within the scaffold's content. ```kotlin import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material3.* // Assuming Material 3 components are used import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @Composable fun ScaffoldExample() { var presses by remember { mutableIntStateOf(0) } Scaffold( topBar = { TopAppBar( colors = topAppBarColors( containerColor = MaterialTheme.colorScheme.primaryContainer, titleContentColor = MaterialTheme.colorScheme.primary, ), title = { Text("Top app bar") } ) }, bottomBar = { BottomAppBar( containerColor = MaterialTheme.colorScheme.primaryContainer, contentColor = MaterialTheme.colorScheme.primary, ) { Text( modifier = Modifier .fillMaxWidth(), textAlign = TextAlign.Center, text = "Bottom app bar", ) } }, floatingActionButton = { FloatingActionButton(onClick = { presses++ }) { Icon(Icons.Default.Add, contentDescription = "Add") } } ) { innerPadding -> Column( modifier = Modifier .padding(innerPadding), verticalArrangement = Arrangement.spacedBy(16.dp), ) { Text( modifier = Modifier.padding(8.dp), text = """ This is an example of a scaffold. It uses the Scaffold composable's parameters to create a screen with a simple top app bar, bottom app bar, and floating action button. It also contains some basic inner content, such as this text. You have pressed the floating action button $presses times. """.trimIndent(), ) } } } ``` -------------------------------- ### Basic Snackbar Example Source: https://developer.android.com/develop/ui/compose/components/snackbar Demonstrates how to show a simple Snackbar with a message. Use this for providing non-critical feedback. ```kotlin val snackbarHostState = remember { SnackbarHostState() } val coroutineScope = rememberCoroutineScope() Scaffold( snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, floatingActionButton = { FloatingActionButton(onClick = { coroutineScope.launch { snackbarHostState.showSnackbar("Message") } }) { Icon(Icons.Default.Add, contentDescription = "Show Snackbar") } } ) { Text("Content") } ``` -------------------------------- ### Handle Session Started Callback (Kotlin) Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/foldables/support-foldable-display-modes Callback invoked when a window area session is successfully started. Logs the event. ```kotlin override fun onSessionStarted(session: WindowAreaSession) { Log.d(logTag, "onSessionStarted") } ``` -------------------------------- ### Assist Chip Example Source: https://developer.android.com/develop/ui/compose/components/chip Demonstrates how to implement an AssistChip with a leading icon. This chip nudges the user in a specific direction. ```kotlin import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.AssistChip import androidx.compose.material3.AssistChipDefaults import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import android.util.Log @Composable fun AssistChipExample() { AssistChip( onClick = { Log.d("Assist chip", "hello world") }, label = { Text("Assist chip") }, leadingIcon = { Icon( Icons.Filled.Settings, contentDescription = "Localized description", modifier = Modifier.size(AssistChipDefaults.IconSize) ) } ) } @Preview @Composable fun PreviewAssistChip() { AssistChipExample() } ``` -------------------------------- ### Handle Session Started Callback (Java) Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/foldables/support-foldable-display-modes Callback invoked when a window area session is successfully started. Logs the event. ```java @Override public void onSessionStarted(){ Log.d(logTag, "onSessionStarted"); } ``` -------------------------------- ### Basic ConstraintLayout Example Source: https://developer.android.com/develop/ui/compose/layouts/constraintlayout This example demonstrates how to use ConstraintLayout in Compose. It shows how to create references for composables and define constraints using the 'constrainAs' modifier and 'linkTo' method. ```kotlin @Composable fun ConstraintLayoutContent() { ConstraintLayout { // Create references for the composables to constrain val (button, text) = createRefs() Button( onClick = { /* Do something */ }, // Assign reference "button" to the Button composable // and constrain it to the top of the ConstraintLayout modifier = Modifier.constrainAs(button) { top.linkTo(parent.top, margin = 16.dp) } ) { Text("Button") } // Assign reference "text" to the Text composable // and constrain it to the bottom of the Button composable Text( "Text", Modifier.constrainAs(text) { top.linkTo(button.bottom, margin = 16.dp) } ) } } ``` -------------------------------- ### Shared Element Navigation 3 Setup Source: https://developer.android.com/develop/ui/compose/animation/shared-elements/navigation This composable demonstrates the setup required for shared element transitions with Navigation 3. It wraps the NavDisplay in a SharedTransitionLayout and passes the appropriate scopes to the screen composables. ```kotlin import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.compose.NavDisplay import androidx.navigation.compose.entry import androidx.navigation.compose.entryProvider import androidx.navigation.compose.rememberNavBackStack import androidx.navigation.compose.LocalNavAnimatedContentScope import androidx.navigation.compose.AnimatedContentScope import androidx.navigation.compose.NavEntry import com.google.samples.apps.sharedtransitions.listSnacks import com.google.samples.apps.sharedtransitions.ui.DetailsRoute import com.google.samples.apps.sharedtransitions.ui.HomeScreen import com.google.samples.apps.sharedtransitions.ui.DetailsScreen import com.google.samples.apps.sharedtransitions.ui.HomeRoute import androidx.compose.animation.SharedTransitionLayout import androidx.compose.animation.SharedTransitionScope @Composable fun SharedElement_Nav3() { SharedTransitionLayout { val backStack = rememberNavBackStack(HomeRoute) // Note: NavDisplay accepts a `sharedTransitionScope` parameter, which is used to animate // NavEntry instances between scenes. This parameter *isn't* required for shared element // or shared bounds transitioning elements between different NavEntry, as demonstrated in // this sample. // See https://developer.android.com/guide/navigation/navigation-3/animate-destinations#transition-nav-entries NavDisplay( modifier = Modifier.safeDrawingPadding(), backStack = backStack, entryProvider = entryProvider { entry { HomeScreen( sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = LocalNavAnimatedContentScope.current, onItemClick = { backStack.add(DetailsRoute(it)) }) } entry { val id = detailsRoute.item val snack = listSnacks[id] DetailsScreen( id = id, snack = snack, sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = LocalNavAnimatedContentScope.current, onBackPressed = { backStack.removeLastOrNull() }, ) } }) } } ``` -------------------------------- ### Small Top App Bar Example Source: https://developer.android.com/develop/ui/compose/components/app-bars A basic small top app bar with a title. This example does not implement scroll behavior. ```kotlin import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview @Composable fun SmallTopAppBarExample() { Scaffold( topBar = { TopAppBar( colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.primaryContainer, titleContentColor = MaterialTheme.colorScheme.primary, ), title = { Text("Small Top App Bar") } ) }, ) { // Inner content } } @Preview(showBackground = true) @Composable fun PreviewSmallTopAppBarExample() { SmallTopAppBarExample() } ``` -------------------------------- ### Configure Drag Source to Start New Instance on Unhandled Drop Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/support-desktop-windowing Implement drag-and-drop functionality that allows users to start a new instance of your app by dropping content onto an empty screen area. This requires providing an `IntentSender` for the system to launch a new activity. ```kotlin Modifier.dragAndDropSource { _ -> val intent = Intent.makeMainActivity(activity.componentName).apply { putExtra("EXTRA_ITEM_ID", itemId) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK or Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT } val pendingIntent = PendingIntent.getActivity( activity, 0, intent, PendingIntent.FLAG_IMMUTABLE ) val data = ClipData( "Item $itemId", arrayOf(ClipDescription.MIMETYPE_TEXT_INTENT), ClipData.Item.Builder().setIntentSender(pendingIntent.intentSender).build() ) DragAndDropTransferData( clipData = data, flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION or View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG ) } ``` -------------------------------- ### Decoupled ConstraintLayout Example Source: https://developer.android.com/develop/ui/compose/layouts/constraintlayout Demonstrates how to use ConstraintLayout with a decoupled ConstraintSet. The constraints adapt based on the available screen width. ```kotlin @Composable fun DecoupledConstraintLayout() { BoxWithConstraints { val constraints = if (minWidth < 600.dp) { decoupledConstraints(margin = 16.dp) // Portrait constraints } else { decoupledConstraints(margin = 32.dp) // Landscape constraints } ConstraintLayout(constraints) { Button( onClick = { /* Do something */ }, modifier = Modifier.layoutId("button") ) { Text("Button") } Text("Text", Modifier.layoutId("text")) } } } private fun decoupledConstraints(margin: Dp): ConstraintSet { return ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") constrain(button) { top.linkTo(parent.top, margin = margin) } constrain(text) { top.linkTo(button.bottom, margin) } } } ``` -------------------------------- ### Handle Content Capture Success URI Source: https://developer.android.com/develop/ui/compose/touch-input/stylus-input/create-a-note-taking-app A simplified example showing how to retrieve the content URI when content capture is successful. ```kotlin registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> if (result.resultCode == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) { val uri = result.data?.data // Use the URI to paste the captured content into the note. } } ``` -------------------------------- ### Using ScaleButton Source: https://developer.android.com/develop/ui/compose/touch-input/user-interactions/handling-interactions Example of how to use the ScaleButton composable with an icon and text. This demonstrates the reusability and integration of the custom button. ```kotlin ScaleButton(onClick = {}) { Icon(Icons.Filled.ShoppingCart, "") Spacer(Modifier.padding(10.dp)) Text(text = "Add to cart!") } Interactions.kt ``` -------------------------------- ### Display Google Map in Compose Source: https://developer.android.com/develop/ui/compose/libraries This example demonstrates how to embed a Google Map into your Compose UI. It requires the Maps Compose library and proper setup for camera positioning and markers. ```kotlin @Composable fun MapsExample() { val singapore = LatLng(1.35, 103.87) val cameraPositionState = rememberCameraPositionState { position = CameraPosition.fromLatLngZoom(singapore, 10f) } GoogleMap( modifier = Modifier.fillMaxSize(), cameraPositionState = cameraPositionState ) { Marker( state = remember { MarkerState(position = singapore) }, title = "Singapore", snippet = "Marker in Singapore" ) } } ComposeWithOtherLibraries.kt ``` -------------------------------- ### Previewing TabletopLayout with Custom UiMediaScope Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/mediaquery This example shows how to preview a `TabletopLayout` by enabling the `mediaQuery` function and providing a custom `UiMediaScope` that specifically sets the `windowPosture` to `Tabletop`. This is useful for testing specific layout configurations. ```kotlin @Preview @Composable fun PreviewLayoutForTabletop() { // Step 1: Enable the mediaQuery function ComposeUiFlags.isMediaQueryIntegrationEnabled = true val currentUiMediaScope = LocalUiMediaScope.current // Step 2: Define a custom object implementing the UiMediaScope interface. // The object overrides the windowPosture parameter. // The resolution of the remaining parameters is deferred to the currentUiMediaScope object. val uiMediaScope = remember(currentUiMediaScope) { object : UiMediaScope by currentUiMediaScope { override val windowPosture: UiMediaScope.Posture = UiMediaScope.Posture.Tabletop } } // Step 3: Set the object to the LocalUiMediaScope. CompositionLocalProvider(LocalUiMediaScope provides uiMediaScope) { // Step 4: Call the composable to preview. when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() } } } UiMediaQuery.kt ``` -------------------------------- ### Basic Scaffold Implementation Source: https://developer.android.com/develop/ui/compose/components/scaffold This example demonstrates a complete Scaffold implementation with a top app bar, bottom app bar, and a floating action button. It shows how to use the Scaffold's parameters and apply inner padding to the content. ```kotlin import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material3.BottomAppBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults.topAppBarColors import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @OptIn(ExperimentalMaterial3Api::class) @Composable fun ScaffoldExample() { var presses by remember { mutableIntStateOf(0) } Scaffold( topBar = { TopAppBar( colors = topAppBarColors( containerColor = MaterialTheme.colorScheme.primaryContainer, titleContentColor = MaterialTheme.colorScheme.primary, ), title = { Text("Top app bar") } ) }, bottomBar = { BottomAppBar( containerColor = MaterialTheme.colorScheme.primaryContainer, contentColor = MaterialTheme.colorScheme.primary, ) { Text( modifier = Modifier .fillMaxWidth(), textAlign = TextAlign.Center, text = "Bottom app bar", ) } }, floatingActionButton = { FloatingActionButton(onClick = { presses++ }) { Icon(Icons.Default.Add, contentDescription = "Add") } } ) { innerPadding -> Column( modifier = Modifier .padding(innerPadding), verticalArrangement = Arrangement.spacedBy(16.dp), ) { Text( modifier = Modifier.padding(8.dp), text = """ This is an example of a scaffold. It uses the Scaffold composable's parameters to create a screen with a simple top app bar, bottom app bar, and floating action button. It also contains some basic inner content, such as this text. You have pressed the floating action button $presses times. """.trimIndent(), ) } } } ``` -------------------------------- ### Compose Text Copy and Paste Example Source: https://developer.android.com/develop/ui/compose/touch-input/copy-and-paste Demonstrates copying text from a SelectionContainer and pasting it into a BasicTextField. This setup allows users to select and copy text from a card and then paste it into an input field. ```kotlin val textFieldState = rememberTextFieldState() Column { Card { SelectionContainer { Text("You can copy this text") } } BasicTextField(state = textFieldState) } ``` -------------------------------- ### Retrieve and display application state in GlanceAppWidget Source: https://developer.android.com/develop/ui/compose/glance/glance-app-widget This example shows how to retrieve destinations from a repository and display them in the widget, handling loading, error, and completed states. The repository should be accessed to get the latest cached data on each refresh. ```kotlin class DestinationAppWidget : GlanceAppWidget() { // ... @Composable fun MyContent() { val repository = remember { DestinationsRepository.getInstance() } // Retrieve the cache data everytime the content is refreshed val destinations by repository.destinations.collectAsState(State.Loading) when (destinations) { is State.Loading -> { // show loading content } is State.Error -> { // show widget error content } is State.Completed -> { // show the list of destinations } } } } ``` -------------------------------- ### Example Stability Configuration File Source: https://developer.android.com/develop/ui/compose/performance/stability/fix This file lists classes and packages to be considered stable by the Compose compiler. Each line represents a class or a wildcard pattern. Supports single (*) and double (**) wildcards for package matching. Comments start with '//'. ```text // Consider LocalDateTime stable java.time.LocalDateTime // Consider my datalayer stable com.datalayer.* // Consider my datalayer and all submodules stable com.datalayer.** // Consider my generic type stable based off it's first type parameter only com.example.GenericClass<*,_> ``` -------------------------------- ### Unstable Class Example Source: https://developer.android.com/develop/ui/compose/performance/stability/fix This is an example of an unstable class with a mutable collection property. ```kotlin unstable class Snack { … unstable val tags: Set … } ``` -------------------------------- ### Define a capability for starting an exercise Source: https://developer.android.com/develop/ui/compose/system/shortcuts/adding-capabilities This snippet shows how to define a capability for the `actions.intent.START_EXERCISE` BII in `shortcuts.xml`. It specifies the target package, activity, and how to map the `exercise.name` parameter. ```xml ``` -------------------------------- ### Set Width from WindowInsets (Start) Source: https://developer.android.com/develop/ui/compose/modifiers-list Sets the width of the modifier to match the start window insets, adapting to layout direction. ```kotlin Modifier.windowInsetsStartWidth(insets: WindowInsets) ``` -------------------------------- ### Launching Content Capture Activity Source: https://developer.android.com/develop/ui/compose/touch-input/stylus-input/create-a-note-taking-app?hl=th This example demonstrates how to launch an activity for capturing content using `registerForActivityResult`. It handles the result, including pasting captured content into the note. ```kotlin private val startForResult = registerForActivityResult( ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> if (result.resultCode == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) { val uri = result.data?.data // Use the URI to paste the captured content into the note. } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { NotesTheme { Surface(color = MaterialTheme.colorScheme.background) { CaptureButton( onClick = { Log.i("ContentCapture", "Launching intent...") startForResult.launch(Intent(ACTION_LAUNCH_CAPTURE_CONTENT_FOR_NOTE)) }) } } } } @Composable fun CaptureButton(onClick: () -> Unit) { Button(onClick = onClick) {Text("Capture Content")} } ``` -------------------------------- ### Shared Element Navigation 2 Setup Source: https://developer.android.com/develop/ui/compose/animation/shared-elements/navigation Demonstrates how to set up shared element transitions within Navigation 2. Requires wrapping NavHost in SharedTransitionLayout and passing the scope to composables. ```kotlin import androidx.compose.animation.SharedTransitionLayout import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.SharedTransitionScope import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument // Assume listSnacks is defined elsewhere // val listSnacks: List = ... @Composable fun SharedElement_Nav2() { SharedTransitionLayout { val navController = rememberNavController() NavHost( navController = navController, startDestination = "home", modifier = Modifier.safeDrawingPadding() ) { composable("home") { HomeScreen( sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = this@composable, onItemClick = { navController.navigate("details/$it") }) } composable( "details/{item}", arguments = listOf(navArgument("item") { type = NavType.IntType }) ) { val id = backStackEntry.arguments?.getInt("item") ?: 0 val snack = listSnacks[id] DetailsScreen( id = id, snack = snack, sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = this@composable, onBackPressed = { navController.popBackStack() } ) } } } } ``` -------------------------------- ### Stable Composable Example Source: https://developer.android.com/develop/ui/compose/performance/stability/diagnose This example shows a completely restartable, skippable, and stable composable function. This is generally the preferred state for composables. ```kotlin restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun SnackCollection( stable snackCollection: SnackCollection stable onSnackClick: Function1 stable modifier: Modifier? = @static Companion stable index: Int = @static 0 stable highlight: Boolean = @static true ) ``` -------------------------------- ### Adapt Layout Based on Window Size Classes Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/mediaquery Use derivedMediaQuery to react to changes in windowWidth and windowHeight. This example switches between single, two, and three pane layouts based on predefined window size class thresholds. ```kotlin val narrowerThanMedium by derivedMediaQuery { windowWidth < WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND.dp } val narrowerThanExpanded by derivedMediaQuery { windowWidth < WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND.dp } when { narrowerThanMedium -> SinglePaneLayout() narrowerThanExpanded -> TwoPaneLayout() else -> ThreePaneLayout() } ``` -------------------------------- ### SizeMode.Responsive Example Source: https://developer.android.com/develop/ui/compose/glance/build-ui Implement `SizeMode.Responsive` to allow the AppWidget to define a set of responsive layouts bounded by specific sizes. This mode performs better and allows smoother transitions when the AppWidget is resized. ```kotlin class MyAppWidget : GlanceAppWidget() { companion object { private val SMALL_SQUARE = DpSize(100.dp, 100.dp) private val HORIZONTAL_RECTANGLE = DpSize(250.dp, 100.dp) private val BIG_SQUARE = DpSize(250.dp, 250.dp) } override val sizeMode = SizeMode.Responsive( setOf( SMALL_SQUARE, HORIZONTAL_RECTANGLE, BIG_SQUARE ) ) override suspend fun provideGlance(context: Context, id: GlanceId) { // ... provideContent { MyContent() } } @Composable private fun MyContent() { // Size will be one of the sizes defined above. val size = LocalSize.current Column { if (size.height >= BIG_SQUARE.height) { Text(text = "Where to?", modifier = GlanceModifier.padding(12.dp)) } Row(horizontalAlignment = Alignment.CenterHorizontally) { Button() Button() if (size.width >= HORIZONTAL_RECTANGLE.width) { Button("School") } } if (size.height >= BIG_SQUARE.height) { Text(text = "provided by X") } } } } ``` -------------------------------- ### Filled Card Example Source: https://developer.android.com/develop/ui/compose/quick-guides/content/create-card-as-container Customize the background color of a Card using the `colors` property with `CardDefaults.cardColors`. This example sets a surface variant color. ```kotlin @Composable fun FilledCardExample() { Card( colors = CardDefaults.cardColors( containerColor = MaterialTheme.colorScheme.surfaceVariant, ), modifier = Modifier .size(width = 240.dp, height = 100.dp) ) { Text( text = "Filled", modifier = Modifier .padding(16.dp), textAlign = TextAlign.Center, ) } } ``` -------------------------------- ### Create a Basic 2x3 Grid Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/grid/get-started This example demonstrates how to create a basic 2x3 grid with fixed column and row sizes of 100.dp. Ensure you have defined `Card1` through `Card6` and `Pastel` colors. ```kotlin Grid( config = { repeat(2) { column(100.dp) } repeat(3) { row(100.dp) } } ) { Card1(containerColor = PastelRed) Card2(containerColor = PastelGreen) Card3(containerColor = PastelBlue) Card4(containerColor = PastelPink) Card5(containerColor = PastelOrange) Card6(containerColor = PastelYellow) } DefineGrid.kt ``` -------------------------------- ### Unstable Class Example Source: https://developer.android.com/develop/ui/compose/performance/stability/diagnose This example demonstrates a class marked as unstable by the Compose compiler. The instability arises from the 'tags' parameter, which is a standard collection interface. ```kotlin unstable class Snack { stable val id: Long stable val name: String stable val imageUrl: String stable val price: Long stable val tagline: String unstable val tags: Set = Unstable } ``` -------------------------------- ### Implementing a Preview Parameter Provider Source: https://developer.android.com/develop/ui/compose/tooling/previews Create a class implementing PreviewParameterProvider to supply sample data for @PreviewParameter. The 'values' property should return a sequence of data objects. ```kotlin class UserPreviewParameterProvider : PreviewParameterProvider { override val values = sequenceOf( User("Elise"), User("Frank"), User("Julia") ) } ``` -------------------------------- ### Preview with System UI Source: https://developer.android.com/develop/ui/compose/tooling/previews Use `showSystemUi = true` to display the status and action bars within your composable preview. ```kotlin import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview @Preview(showSystemUi = true) @Composable fun DecoratedComposablePreview() { Text("Hello World") } ``` -------------------------------- ### Complete Custom Modifier Example with Modifier.Node Source: https://developer.android.com/develop/ui/compose/custom-modifiers This example integrates the ModifierNodeElement, modifier factory, and the Modifier.Node implementation to create a functional custom modifier for drawing a circle. ```kotlin fun Modifier.circle(color: Color) = this then CircleElement(color) private data class CircleElement(val color: Color) : ModifierNodeElement() { override fun create() = CircleNode(color) override fun update(node: CircleNode) { node.color = color } } private class CircleNode(var color: Color) : DrawModifierNode, Modifier.Node() { override fun ContentDrawScope.draw() { drawCircle(color) } } ``` -------------------------------- ### Launch activity with action parameters Source: https://developer.android.com/develop/ui/compose/glance/user-interaction Use `actionStartActivity` with `actionParametersOf` to launch `NavigationActivity` and pass a destination parameter. ```kotlin Button( text = "Home", onClick = actionStartActivity( actionParametersOf(destinationKey to "home") ) ) ``` ```kotlin Button( text = "Work", onClick = actionStartActivity( actionParametersOf(destinationKey to "work") ) ) ``` -------------------------------- ### Create a Basic Dropdown Menu Source: https://developer.android.com/develop/ui/compose/components/menu Demonstrates a minimal DropdownMenu implementation with two selectable options. The menu's visibility is controlled by an 'expanded' state, and it dismisses when the user clicks outside of it. ```kotlin import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @Composable fun MinimalDropdownMenu() { var expanded by remember { mutableStateOf(false) } Box( modifier = Modifier .padding(16.dp) ) { IconButton(onClick = { expanded = !expanded }) { Icon(Icons.Default.MoreVert, contentDescription = "More options") } DropdownMenu( expanded = expanded, onDismissRequest = { expanded = false } ) { DropdownMenuItem( text = { Text("Option 1") }, onClick = { /* Do something... */ } ) DropdownMenuItem( text = { Text("Option 2") }, onClick = { /* Do something... */ } ) } } } ``` -------------------------------- ### Collect WindowLayoutInfo with Kotlin Flows Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/foldables/make-your-app-fold-aware Use `repeatOnLifecycle` with `STARTED` state to collect `WindowLayoutInfo` updates. This ensures data collection starts when the activity is visible and stops when it's not. ```kotlin class DisplayFeaturesActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { // ... lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { WindowInfoTracker.getOrCreate(this@DisplayFeaturesActivity) .windowLayoutInfo(this@DisplayFeaturesActivity) .collect { newLayoutInfo -> // Use newLayoutInfo to update the layout. } } } } } MakeYourAppFoldAware.kt ``` -------------------------------- ### Set up NavHost in App Composable Source: https://developer.android.com/develop/ui/compose/migrate/migration-scenarios/navigation Create and configure the NavHost within your App composable, passing the initialized NavController. This establishes the navigation structure for your application. ```kotlin @Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } } ``` -------------------------------- ### Align Pager Pages to End with Start Padding Source: https://developer.android.com/develop/ui/compose/layouts/pager Use `PaddingValues(start = ...)` to align pages towards the end of the pager. This influences the maximum size and alignment of pages. ```kotlin val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { // page content } ``` -------------------------------- ### Setting up Material Theme and Surface Source: https://developer.android.com/develop/ui/compose/tutorial Wrap your root composables with `ComposeTutorialTheme` and `Surface` to inherit theme styles. This is done in both the `setContent` function for the running app and the `@Preview` composable. ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ComposeTutorialTheme { Surface(modifier = Modifier.fillMaxSize()) { MessageCard(Message("Android", "Jetpack Compose")) } } } } } ``` ```kotlin @Preview @Composable fun PreviewMessageCard() { ComposeTutorialTheme { Surface { MessageCard( msg = Message("Lexi", "Take a look at Jetpack Compose, it's great!") ) } } } ``` -------------------------------- ### Start Animation on Composable Launch Source: https://developer.android.com/develop/ui/compose/animation/quick-guide Utilize `LaunchedEffect` to trigger animations when a composable enters the composition. The `Animatable` API with `animateTo` is suitable for starting animations immediately upon launch. ```kotlin val alphaAnimation = remember { Animatable(0f) } LaunchedEffect(Unit) { alphaAnimation.animateTo(1f) } Box( modifier = Modifier.graphicsLayer { alpha = alphaAnimation.value } ) ``` -------------------------------- ### Align Pager Pages to Start with End Padding Source: https://developer.android.com/develop/ui/compose/layouts/pager Utilize `PaddingValues(end = ...)` to align pages towards the start of the pager. This setting impacts the maximum size and alignment of individual pages. ```kotlin val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { // page content } ``` -------------------------------- ### Basic List-Detail Pane Scaffold Implementation Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/canonical-layouts This is a minimal implementation of a list-detail layout using `ListDetailPaneScaffold`. It sets up the scaffold with a navigator to manage pane visibility and content switching based on window size classes. The `listPane` and `detailPane` lambdas are placeholders for your actual list and detail content. ```kotlin @OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun MyListDetailPaneScaffold() { val navigator = rememberListDetailPaneScaffoldNavigator() ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { // Listing Pane }, detailPane = { // Details Pane } ) } CanonicalLayoutSamples.kt ``` -------------------------------- ### Configure NavHost for Predictive Back Animations Source: https://developer.android.com/develop/ui/compose/system/predictive-back-setup Use `popExitTransition` to define how the exiting screen animates during a predictive back gesture. This example uses `scaleOut` to scale down the exiting screen. ```kotlin NavHost( navController = navController, startDestination = Home, popExitTransition = { scaleOut( targetScale = 0.9f, transformOrigin = TransformOrigin(pivotFractionX = 0.5f, pivotFractionY = 0.5f) ) }, popEnterTransition = { EnterTransition.None }, modifier = modifier, ) ``` -------------------------------- ### Complete Supporting Pane Layout Implementation Source: https://developer.android.com/develop/ui/compose/layouts/adaptive/build-a-supporting-pane-layout A full example demonstrating the `NavigableSupportingPaneScaffold` with logic to show/hide the supporting pane and handle back navigation. It uses `AnimatedPane` for transitions and `PaneAdaptedValue` to check pane states. ```kotlin val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() val backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { AnimatedPane( modifier = Modifier .safeContentPadding() .background(Color.Red) ) { if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) { Button( modifier = Modifier .wrapContentSize(), onClick = { scope.launch { scaffoldNavigator.navigateTo(SupportingPaneScaffoldRole.Supporting) } } ) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } }, supportingPane = { AnimatedPane(modifier = Modifier.safeContentPadding()) { Column { // Allow users to dismiss the supporting pane. Use back navigation to // hide an expanded supporting pane. if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Expanded) { // Material design principles promote the usage of a right-aligned // close (X) button. IconButton( modifier = Modifier.align(Alignment.End).padding(16.dp), onClick = { scope.launch { scaffoldNavigator.navigateBack(backNavigationBehavior) } } ) { Icon(Icons.Default.Close, contentDescription = "Close") } } Text("Supporting pane") } } } ) SampleSupportingPaneScaffold.kt ``` -------------------------------- ### Calculate Gradient Start and End from Press Position Source: https://developer.android.com/develop/ui/compose/touch-input/user-interactions/handling-interactions Calculates the start and end points for a gradient based on the user's press position and the bounding rectangle size. This is useful for creating visual feedback effects. ```kotlin private fun calculateGradientStartAndEndFromPressPosition( pressPosition: Offset, size: Size ): Pair { // Convert to offset from the center val offset = pressPosition - size.center // y = mx + c, c is 0, so just test for x and y to see where the intercept is val gradient = offset.y / offset.x // We are starting from the center, so halve the width and height - convert the sign // to match the offset val width = (size.width / 2f) * sign(offset.x) val height = (size.height / 2f) * sign(offset.y) val x = height / gradient val y = gradient * width // Figure out which intercept lies within bounds val intercept = if (abs(y) <= abs(height)) { Offset(width, y) } else { Offset(x, height) } // Convert back to offsets from 0,0 val start = intercept + size.center val end = Offset(size.width - start.x, size.height - start.y) return start to end } ``` -------------------------------- ### Video Playback PiP Implementation Source: https://developer.android.com/develop/ui/compose/system/pip-jetpack This snippet demonstrates a Picture-in-Picture implementation specifically for video playback scenarios using VideoPlaybackPictureInPicture. It covers setting up the delegate, handling playback-related PiP events, and managing the lifecycle of the PiP controller. ```kotlin class VideoPlaybackJpipActivity : ComponentActivity(), PictureInPictureDelegate.OnPictureInPictureEventListener { private lateinit var pictureInPictureImpl: VideoPlaybackPictureInPicture override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) pictureInPictureImpl = VideoPlaybackPictureInPicture(this) pictureInPictureImpl.addOnPictureInPictureEventListener( ContextCompat.getMainExecutor(this), this ) setContent { ContentScreen(pictureInPictureImpl) } } override fun onPictureInPictureEvent( event: PictureInPictureDelegate.Event, config: Configuration? ) { when (event) { PictureInPictureDelegate.Event.ENTER_ANIMATION_START -> { /* Hide overlays */ } PictureInPictureDelegate.Event.ENTER_ANIMATION_END -> { /* Animation finished */ } PictureInPictureDelegate.Event.ENTERED -> { /* Switch to PiP layout */ } PictureInPictureDelegate.Event.STASHED -> { /* PiP stashed */ } PictureInPictureDelegate.Event.UNSTASHED -> { /* PiP unstashed */ } PictureInPictureDelegate.Event.EXITED -> { /* Return to full-screen */ } } } @Composable fun ContentScreen(pipController: VideoPlaybackPictureInPicture) { DisposableEffect(pipController) { onDispose { pipController.close() } } } } VideoPlaybackJpipActivity.kt ``` -------------------------------- ### Basic Continuous Range Slider Example Source: https://developer.android.com/develop/ui/compose/quick-guides/content/create-range-slider This example shows a simple continuous range slider. It uses `remember` and `mutableStateOf` to manage the slider's state. The `steps` parameter defines discrete intervals, and `valueRange` sets the overall bounds. ```kotlin @Preview @Composable fun RangeSliderExample() { var sliderPosition by remember { mutableStateOf(0f..100f) } Column { RangeSlider( value = sliderPosition, steps = 5, onValueChange = { range -> sliderPosition = range }, valueRange = 0f..100f, onValueChangeFinished = { // launch some business logic update with the state you hold // viewModel.updateSelectedSliderValue(sliderPosition) }, ) Text(text = sliderPosition.toString()) } } ``` -------------------------------- ### Compose Input Chip Example Source: https://developer.android.com/develop/ui/compose/components/chip Demonstrates an InputChip that is initially selected and can be dismissed by the user. Use this for interactive elements like contacts in an email. ```kotlin import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Close import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.InputChip import androidx.compose.material3.InputChipDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier @OptIn(ExperimentalMaterial3Api::class) @Composable fun InputChipExample( text: String, onDismiss: () -> Unit, ) { var enabled by remember { mutableStateOf(true) } if (!enabled) return InputChip( onClick = { onDismiss() enabled = !enabled }, label = { Text(text) }, selected = enabled, avatar = { Icon( Icons.Filled.Person, contentDescription = "Localized description", Modifier.size(InputChipDefaults.AvatarSize) ) }, trailingIcon = { Icon( Icons.Default.Close, contentDescription = "Localized description", Modifier.size(InputChipDefaults.AvatarSize) ) }, ) } ``` -------------------------------- ### Revoke Notification Permission for New Installs on Android 13+ Source: https://developer.android.com/develop/ui/compose/notifications/notification-permission Use these ADB commands to simulate a new app installation on Android 13+ where the notification permission is initially revoked. This helps test how your app handles the permission request flow. ```bash adb shell pm revoke PACKAGE_NAME android.permission.POST_NOTIFICATIONS adb shell pm clear-permission-flags PACKAGE_NAME \ android.permission.POST_NOTIFICATIONS user-set adb shell pm clear-permission-flags PACKAGE_NAME \ android.permission.POST_NOTIFICATIONS user-fixed ``` -------------------------------- ### Using ModalNavigationDrawer for drawers in M3 Source: https://developer.android.com/develop/ui/compose/designsystems/material2-material3 Illustrates the M3 approach using `ModalNavigationDrawer` and `ModalDrawerSheet` for navigation drawers, with `Scaffold` handling the main content. ```kotlin import androidx.compose.material3.DrawerValue import androidx.compose.material3.ModalDrawerSheet import androidx.compose.material3.ModalNavigationDrawer import androidx.compose.material3.Scaffold import androidx.compose.material3.rememberDrawerState val drawerState = rememberDrawerState(DrawerValue.Closed) val scope = rememberCoroutineScope() ModalNavigationDrawer( drawerState = drawerState, drawerContent = { ModalDrawerSheet( drawerShape = …, drawerTonalElevation = …, drawerContainerColor = …, drawerContentColor = …, content = { … } ) }, gesturesEnabled = …, scrimColor = …, content = { Scaffold( content = { … scope.launch { drawerState.open() } } ) } ) ``` -------------------------------- ### Basic state-based TextField Source: https://developer.android.com/develop/ui/compose/text/migrate-state-based Example of a simple state-based TextField using `rememberTextFieldState` and `TextFieldLineLimits.SingleLine`. ```kotlin import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldLineLimits import androidx.compose.material3.rememberTextFieldState import androidx.compose.runtime.Composable @Composable fun NewSimpleTextField() { TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine ) } ``` -------------------------------- ### Basic value-based TextField Source: https://developer.android.com/develop/ui/compose/text/migrate-state-based Example of a simple value-based TextField using `rememberSaveable` and `mutableStateOf`. ```kotlin import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue @Composable fun OldSimpleTextField() { var state by rememberSaveable { mutableStateOf("") } TextField( value = state, onValueChange = { state = it }, singleLine = true, ) } ``` -------------------------------- ### Example screen with animated list controls Source: https://developer.android.com/develop/ui/compose/lists This composable presents a screen with buttons to add, remove, and sort items in an animated list. It demonstrates how to integrate controls with the `ListAnimatedItems` composable. ```kotlin @Composable private fun ListAnimatedItemsExample( data: List, modifier: Modifier = Modifier, onAddItem: () -> Unit = {}, onRemoveItem: () -> Unit = {}, resetOrder: () -> Unit = {}, onSortAlphabetically: () -> Unit = {}, onSortByLength: () -> Unit = {}, ) { val canAddItem = data.size < 10 val canRemoveItem = data.isNotEmpty() Scaffold(modifier) { Column( modifier = Modifier .padding(it) .fillMaxSize() ) { // Buttons that change the value of displayedItems. AddRemoveButtons(canAddItem, canRemoveItem, onAddItem, onRemoveItem) OrderButtons(resetOrder, onSortAlphabetically, onSortByLength) // List that displays the values of displayedItems. ListAnimatedItems(data) } } } ```