{"id":18687983,"url":"https://github.com/anitaa1990/jetpackcomposesample","last_synced_at":"2025-04-12T05:31:35.110Z","repository":{"id":243501685,"uuid":"811987400","full_name":"anitaa1990/JetpackComposeSample","owner":"anitaa1990","description":"Small write ups on everything Compose - for anyone like me, looking to develop apps using Jetpack Compose","archived":false,"fork":false,"pushed_at":"2024-11-29T08:34:01.000Z","size":74371,"stargazers_count":4,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T00:51:23.124Z","etag":null,"topics":["android","android-app","jetpack-android","jetpack-compose","jetpack-compose-tutorial","kotlin","kotlin-android","sample-app"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anitaa1990.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-07T17:56:50.000Z","updated_at":"2025-01-22T09:06:33.000Z","dependencies_parsed_at":"2024-06-19T13:54:13.635Z","dependency_job_id":null,"html_url":"https://github.com/anitaa1990/JetpackComposeSample","commit_stats":null,"previous_names":["anitaa1990/jetpackcomposesample"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anitaa1990%2FJetpackComposeSample","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anitaa1990%2FJetpackComposeSample/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anitaa1990%2FJetpackComposeSample/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anitaa1990%2FJetpackComposeSample/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anitaa1990","download_url":"https://codeload.github.com/anitaa1990/JetpackComposeSample/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248523791,"owners_count":21118563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-app","jetpack-android","jetpack-compose","jetpack-compose-tutorial","kotlin","kotlin-android","sample-app"],"created_at":"2024-11-07T10:35:07.954Z","updated_at":"2025-04-12T05:31:35.022Z","avatar_url":"https://github.com/anitaa1990.png","language":"Kotlin","readme":"# Jetpack Compose Samples\n\u003cimg src=\"https://github.com/anitaa1990/JetpackComposeSample/blob/master/media/img_jetpack_compose.png\"\u003e\n\n## Contents\n- [What is Jetpack Compose?](#what-is-jetpack-compose)\n- [Advantages of Jetpack Compose](#advantages-of-jetpack-compose)\n- [Composable function](#composable-function)\n- [State management in Compose](#state-management-in-compose)\n- [Jetpack Compose Preview](#jetpack-compose-preview)\n- [Rows](#rows)\n- [Columns](#columns)\n- [Box](#box)\n- [Compose Modifiers](#compose-modifiers)\n- [Text](#text)\n- [Button](#buttons)\n- [Image](#image)\n- [TextField](#textfield)\n- [Lazy Grids](#lazy-grids)\n- [Lazy Lists](#lazy-lists)\n- [Scaffold](#scaffold) (topAppBar, floatingActionButton, bottomBar)\n- [Card](#card)\n- [Progress Indicators](#progress-indicators)\n- [Alert Dialog](#alert-dialog)\n- [Custom Dialog](#custom-dialog)\n- [DatePicker Dialog](#datepicker-dialog)\n- [BottomSheet](#bottomsheet)\n- [RadioButton](#radiobutton)\n- [CheckBox](#checkbox)\n- [Slider](#slider)\n- [Switch](#switch)\n- [Chips](#chips)\n- [Tabs](#tabs)\n- [Bottom Navigation Bar](#bottom-navigation-bar)\n- [Dynamic themes](#dynamic-themes)\n- [Switching between dark and light mode](#switching-between-dark-mode-and-light-mode)\n- [Navigation in Compose](#navigation-in-compose)\n\n### What is Jetpack Compose?\nJetpack Compose is Android’s **recommended** modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Jetpack Compose is _declarative programming_, which means you can describe your user interface by invoking a set of composables, which is vastly different from the traditional way of imperative UI design.\n\n### Advantages of Jetpack Compose\n- Compose uses a declarative API, which means that all you need to do is describe your UI - Compose takes care of the rest. The APIs are intuitive - easy to discover and use.\n- Compose is compatible with all your existing code: you can call Compose code from Views and Views from Compose.\n- Compose allows you to do more with less code, compared to using the Android View system.\n- With Composable functions, state can be handled reactively. When the state changes, only the parts of the UI that depend on this state are automatically and efficiently re-rendered. This is achieved through the use of state holders and observable state variables, which triggers the recomposition of the Composable functions they are used in.\n\n### Composable function\nA composable function is a modern way of developing UI in Android. It is a Kotlin function that is annotated with `@Composable`. This annotation tells the Compose compiler that the functions is meant for UI construction. Unlike tradition XML layouts in Android, Composable functions allow us to build UI with Kotlin code which is more intuitive and flexible. Composable functions can only be called from within the scope of other composable functions. We should think of composable functions to be similar to lego blocks - each composable function is in turn built up of smaller composable functions.\n```\n@Composable\nfun HelloWorld(name: String) {\n    Text(text = \"Hello, $name!\")\n}\n```\n\n### State management in Compose\nWith Composable functions, state can be handled reactively. When the state changes, only the parts of the UI that depend on this state are automatically and efficiently re-rendered. This is achieved through the use of state holders and observable state variables, which triggers the recomposition of the Composable functions they are used in. Compose provides `State` (read-only) and `MutableState` (read-write).\n\nThere are two main ways to manage state in Jetpack Compose.\n1. Stateful composables** are composables that manage their own state. This state is typically stored within the composable function itself, using tools provided by Jetpack Compose, such as `remember` or `mutableStateOf`. When the state changes, the composable recomposes itself, updating the UI with the new state.\n\n```\nvar darkTheme by remember { mutableStateOf(false) }\n```\n2. **Stateless composables** are those that do not manage their own state internally. Instead, they receive their state through parameters and emit events to notify the parent composable of any changes. In the below example, the `SimpleButton` composable is stateless. It receives the text and onClick event through its parameters and does not manage any state.\n\n```\n@Composable\nfun StatelessScreen() {\n    val text = \"Click me!\"\n    SimpleButton(text = text) { /* Handle click event */ }\n}\n```\n\n### Jetpack Compose Preview\nCompose comes with this nifty feature that lets you preview each component in the IntelliJ IDE itself, instead of needing to download the app to an Android device or emulator. To do so, we need to define `@Preview` to any of the `@Composable` methods and click on the preview button in the top right corner. The main restriction is, the composable function must not take any parameters. If your composable function requires a parameter, you can simply wrap your component inside another composable function that doesn't take any parameters and call your composable function with the appropriate params.\n\n\u003cimg src=\"https://github.com/anitaa1990/JetpackComposeSample/blob/master/media/img_compose_preview.png\"\u003e\n\n### Rows\nA `Row` is a horizontal layout component in Jetpack Compose. It is used to position UI elements horizontally. You can add any number of children to a row, and they will be laid out horizontally in the order they were added. By default, the row will take up as much horizontal space as possible, and the children will be sized to fit within the row’s boundaries.\n\n| Example                                                                        | Preview                                                                                       |\n|--------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|\n| [RowScreen](app/src/main/java/com/an/jetpackcomposesample/screen/RowScreen.kt) | \u003cimg src =\"media/row/img_row_1.png\" width=300\u003e\u003cimg src =\"/media/row/img_row_2.png\" width=300\u003e |\n\n```\n@Composable\nprivate fun RowStyle() {\n    Row(\n        modifier = Modifier\n            // will set the min and max width of the composble to the maximum allowed by the container\n            .fillMaxWidth()\n            .padding(12.dp)\n            .background(MaterialTheme.colorScheme.inverseOnSurface, shape = RoundedCornerShape(10.dp)),\n        // The horizontalArrangement parameter controls the way free space is distributed between items.\n        horizontalArrangement = Arrangement.Start)\n{\n        Text(text = \"A\")\n        Text(text = \"B\")\n        Text(text = \"C\")\n    }\n}\n```\n\n### Columns\nA column is a vertical layout component in Jetpack Compose. It is used to position UI elements vertically. You can add any number of children to a column, and they will be laid out vertically in the order they were added. By default, the column will take up as much vertical space as possible, and the children will be sized to fit within the column’s boundaries.\n\n| Example                                                                              | Preview                                                                                                   |\n|--------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|\n| [ColumnScreen](app/src/main/java/com/an/jetpackcomposesample/screen/ColumnScreen.kt) | \u003cimg src =\"media/column/img_column_1.gif\" width=300\u003e\u003cimg src =\"/media/column/img_column_2.gif\" width=300\u003e |\n\n```\n@Composable\nprivate fun ColumnStyle() {\n    Column(modifier = Modifier\n        .fillMaxHeight(0.5f)\n        .fillMaxWidth()\n        .padding(12.dp)\n        .alpha(1f)\n        .background(MaterialTheme.colorScheme.inverseOnSurface, shape = RoundedCornerShape(10.dp)),\n        verticalArrangement = arrangement\n    ) {\n        Text(text = \"A\")\n        Text(text = \"B\")\n        Text(text = \"C\")\n    }\n}\n```\n\n### Box\nA box is a layout component that allows you to position a single UI element anywhere within its boundaries. You can add any UI element to a box and position it by specifying its alignment within the box.\n```\nBox(\n   modifier = Modifier.size(size),\n   contentAlignment = Alignment.Center\n) {\n    Text(\"Center\", Modifier.align(Alignment.Center))\n    Text(\"Top Start\", Modifier.align(Alignment.TopStart))\n    Text(\"Top End\", Modifier.align(Alignment.TopEnd))\n    Text(\"Bottom Start\", Modifier.align(Alignment.BottomStart))\n    Text(\"Bottom End\", Modifier.align(Alignment.BottomEnd))\n }\n```\n\n### Compose Modifiers\nModifier elements decorate or add behavior to Compose UI elements. For example, backgrounds, padding and click event listeners decorate or add behavior to rows, text or buttons. Modifiers are standard Kotlin objects. We can create a modifier by calling one of the `Modifier` class functions.\n```\nText(\"Text with green background color\",\n    modifier = Modifier\n                .background(color = Color.Green)) // background color\n                .padding(16.dp) // inner padding\n                .width(200.dp) // define width \u0026 height separately\n                .height(300.dp)\n                .size(width = 250.dp, height = 100.dp) // OR add size\n                .alpha(0.5f) // 50% opacity\n                .rotate(45f) // Sets the degrees the view is rotated around the center of the composable.\n                .scale(scaleX = 2f, scaleY = 3f) // Scale the contents of the composable by the following scale factors along the horizontal and vertical axis respectively.\n                .weight(1f) // you can specify a size ratio between multiple views\n                .border(2.dp,Color.Red) // adds border to the text\n                .clip(RoundedCornerShape(25.dp)) // allows you to clip the existing shape\n```\n\n### Text\n`Text` is a central piece of any UI, and Jetpack Compose makes it easier to display or write text. Attributes of the `Text` composable include:\n```\n@Composable\nfun Text(\n    text: String,                                        // the text to be displayed\n    modifier: Modifier = Modifier,                       // the Modifier to be applied to this layout node\n    color: Color = Color.Unspecified,                    // Color to apply to the text\n    fontSize: TextUnit = TextUnit.Unspecified,           // the size of glyphs to use when painting the text\n    fontStyle: FontStyle? = null,                        // the typeface variant to use when drawing the letters (e.g., italic)\n    fontWeight: FontWeight? = null,                      // the typeface thickness to use when painting the text\n    fontFamily: FontFamily? = null,                      // the font family to be used when rendering the text\n    letterSpacing: TextUnit = TextUnit.Unspecified,      // the amount of space to add between each letter\n    textDecoration: TextDecoration? = null,              // the decorations to paint on the text (e.g., an underline)  \n    textAlign: TextAlign? = null,                        // the alignment of the text within the lines of the paragraph\n    lineHeight: TextUnit = TextUnit.Unspecified,         // line height for the Paragraph in TextUnit unit\n    overflow: TextOverflow = TextOverflow.Clip,          // defines how visual overflow should be handled.  \n    softWrap: Boolean = true,                            // whether the text should break at soft line breaks.\n    maxLines: Int = Int.MAX_VALUE,                       // An optional maximum number of lines for the text to span, wrapping if necessary \n    minLines: Int = 1,                                   // The minimum height in terms of minimum number of visible lines.  \n    onTextLayout: ((TextLayoutResult) -\u003e Unit)? = null,  // callback that is executed when a new text layout is calculated.   \n    style: TextStyle = LocalTextStyle.current            // style configuration for the text such as color, font, line height etc.\n)\n```\n| Example                                                                              | Preview                                                                                                   |\n|--------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|\n| [TextScreen](app/src/main/java/com/an/jetpackcomposesample/screen/TextScreen.kt) | \u003cimg src =\"media/text/img_text_1.gif\" width=300\u003e\u003cimg src =\"/media/text/img_text_2.gif\" width=300\u003e |\n\n### Buttons\nButtons are fundamental components that allow the user to trigger a defined action. In Jetpack Compose, you need to give two arguments for buttons. The first argument as `onClick` callback and another one is your button `text` element. You can add a `Text`-Composable or any other Composable as child elements of the Button. There are five types of buttons.\n\n![](media/img_button_types.png)\n*[Reference](https://developer.android.com/develop/ui/compose/components/button)*\n\n```\n@Composable\nfun Button(\n    onClick: () -\u003e Unit,                                              // called when this button is clicked\n    modifier: Modifier = Modifier,                                    // the [Modifier] to be applied to this button  \n    enabled: Boolean = true,                                          // controls the enabled state of this button.\n    shape: Shape = ButtonDefaults.shape,                              // defines the shape of this button's container, border (when [border] is not null), and shadow (when using [elevation])\n    colors: ButtonColors = ButtonDefaults.buttonColors(),             // used to resolve the colors for this button in different states\n    elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),   // used to resolve the elevation for this button in different states. This controls the size of the shadow below the button.\n    border: BorderStroke? = null,                                    // the border to draw around the container of this button\n    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,   // the spacing values to apply internally between the container and the content\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, \n    content: @Composable RowScope.() -\u003e Unit\n) {\n    // Content of the Button\n    Text(text = \"Clicked me!\")\n}\n```\n| Example                                                                              | Preview                                                                                                   |\n|--------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|\n| [ButtonScreen](app/src/main/java/com/an/jetpackcomposesample/screen/ButtonScreen.kt) | \u003cimg src =\"media/button/img_button_1.png\" width=300\u003e\u003cimg src =\"/media/button/img_button_2.png\" width=300\u003e |\n\n### Image\nWe can use the `Image` composable to display a graphic on screen. The different attributes of `Image` are:\n```\n@Composable\nfun Image(\n    painter: Painter,     // loads a drawable from resources. Use painterResource and pass a resource id\n    contentDescription: String?, // to give description about the image\n    modifier: Modifier = Modifier, // defines the modifier for the image\n    alignment: Alignment = Alignment.Center,\n    contentScale: ContentScale = ContentScale.Fit,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null\n)\n\n// Example\n@Composable\nfun SimpleImageExample() {\n    // Image is a pre-defined composable that lays out and draws a given [ImageBitmap]\n    Image(\n        painter = painterResource(id = R.drawable.ic_image),\n        contentDescription = stringResource(id = R.string.image_screen_content_desc),\n        modifier = Modifier\n            .padding(10.dp)\n            .size(120.dp)\n    )\n}\n```\n\n| Example                                                                            | Preview                                                                                               |\n|------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|\n| [ImageScreen](app/src/main/java/com/an/jetpackcomposesample/screen/ImageScreen.kt) | \u003cimg src =\"media/image/img_image_1.gif\" width=300\u003e\u003cimg src =\"/media/image/img_image_2.gif\" width=300\u003e |\n\n### TextField\n`TextField` allows users to enter and modify text. The different attributes of `TextField` are:\n```\n@Composable\nfun TextField(\n    value: TextFieldValue,                      // the input value to be shown in the text field\n    onValueChange: (TextFieldValue) -\u003e Unit,    // the callback that is triggered when user enters any value\n    modifier: Modifier = Modifier,              // defines the modifier for the TextField\n    enabled: Boolean = true,                    // controls the enabled state of this text field\n    readOnly: Boolean = false,                  // controls the editable state of the text field\n    textStyle: TextStyle = LocalTextStyle.current,      // the style to be applied to the input text.\n    label: @Composable (() -\u003e Unit)? = null,            // the optional label to be displayed inside the text field container.\n    placeholder: @Composable (() -\u003e Unit)? = null,      // the optional placeholder to be displayed when the text field is empty\n    leadingIcon: @Composable (() -\u003e Unit)? = null,      // the optional leading icon to be displayed at the beginning of the text field container\n    trailingIcon: @Composable (() -\u003e Unit)? = null,     // the optional trailing icon to be displayed at the end of the text field container\n    prefix: @Composable (() -\u003e Unit)? = null,           // the optional prefix to be displayed before the input text in the text field\n    suffix: @Composable (() -\u003e Unit)? = null,           // the optional suffix to be displayed after the input text in the text field\n    supportingText: @Composable (() -\u003e Unit)? = null,   // the optional supporting text to be displayed below the text field\n    isError: Boolean = false,                                       // indicates if the text field's current value is in error state.\n    visualTransformation: VisualTransformation = VisualTransformation.None,             // transforms the visual representation of the input value\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,                         // software keyboard options that contains configuration such as KeyboardType and ImeAction\n    keyboardActions: KeyboardActions = KeyboardActions.Default,                         // when the input service emits an IME action, the corresponding callback is called.\n    singleLine: Boolean = false,                                    // this text field becomes a single horizontally scrolling text field instead of wrapping onto multiple lines.\n    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,           // the maximum height in terms of maximum number of visible lines\n    minLines: Int = 1,                                              // the minimum height in terms of minimum number of visible lines\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },     \n    shape: Shape = TextFieldDefaults.shape,                         // defines the shape of this text field's container\n    colors: TextFieldColors = TextFieldDefaults.colors()            // [TextFieldColors] that will be used to resolve the colors used for this text field in different states.\n)\n\n// Example\nTextField(\n    value = password,\n    onValueChange = { password = it },\n    label = { Text(\"Enter password\") },\n    visualTransformation = PasswordVisualTransformation(),\n    keyboardOptions = KeyboardOptions(\n    keyboardType = KeyboardType.Password,\n    imeAction = ImeAction.Done\n    )\n) \n```\n\n| Example                                                                                    | Preview                                                                                                               |\n|--------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|\n| [TextFieldScreen](app/src/main/java/com/an/jetpackcomposesample/screen/TextFieldScreen.kt) | \u003cimg src =\"media/textfield/img_textfield_1.png\" width=300\u003e\u003cimg src =\"/media/textfield/img_textfield_2.png\" width=300\u003e |\n\n### Lazy Grids\nVertical staggered grid layout that composes and lays out only items currently visible on screen. Attributes of `Grid` include:\n```\n@Composable\nfun LazyVerticalStaggeredGrid(\n    columns: StaggeredGridCells,                                        // description of the size and number of staggered grid columns.\n    modifier: Modifier = Modifier,                                      // modifier to apply to the layout.\n    state: LazyStaggeredGridState = rememberLazyStaggeredGridState(),   // state object that can be used to control and observe staggered grid state.\n    contentPadding: PaddingValues = PaddingValues(0.dp),                // padding around the content.\n    reverseLayout: Boolean = false,                                     // reverse the direction of scrolling and layout. When `true`, items are laid out in the reverse order\n    verticalItemSpacing: Dp = 0.dp,                                     // vertical spacing between items    \n    horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(0.dp),         // arrangement specifying horizontal spacing between items.\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),                  // logic responsible for handling fling.\n    userScrollEnabled: Boolean = true,                                  // whether scroll with gestures or accessibility actions are allowed.\n    content: LazyStaggeredGridScope.() -\u003e Unit                          // a lambda describing the staggered grid content. Inside this block you can use [LazyStaggeredGridScope.items] to present list of items\n)\n\n// Example\nLazyVerticalStaggeredGrid(\n    columns = StaggeredGridCells.Adaptive(minSize = 180.dp),\n    // applied to outside edges of our content – creating some visual space between the edges of the content and the container\n    // contentPadding = PaddingValues(16.dp),\n    // horizontalArrangement = Arrangement.spacedBy(16.dp)\n    ) {\n        val gridList = (1..20).map {\n            GridModel(it, getRandomColor(), getRandomHeight(), getRandomIcon())\n        }\n        items(gridList.size) {\n            GridItem(modifier, gridList[it])\n        }\n }\n```\n\n| Example                                                                               | Preview                                                                                           |\n|---------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|\n| [GridScreen](app/src/main/java/com/an/jetpackcomposesample/screen/grid/GridScreen.kt) | \u003cimg src =\"media/grid/img_grid_1.gif\" width=300\u003e |\n\n### Lazy Lists\nCompose provides a set of components which only compose and lay out items which are visible in the component’s viewport. These components include `LazyColumn` (Vertical `RecyclerView`) and `LazyRow` (Horizontal `RecyclerView`). In LazyColumn you can add an `item()` or `items()`.\n```\n@Composable\nfun LazyColumn(\n    modifier: Modifier = Modifier,                                          // the modifier to apply to this layout.\n    state: LazyListState = rememberLazyListState(),                         // the state object to be used to control or observe the list's state.\n    contentPadding: PaddingValues = PaddingValues(0.dp),                    // a padding around the whole content.\n    reverseLayout: Boolean = false,                                         // reverse the direction of scrolling and layout.\n    verticalArrangement: Arrangement.Vertical =\n        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,        // The vertical arrangement of the layout's children. This allows to add a spacing between items and specify the arrangement of the items when we have not enough of them to fill the whole minimum size.\n    horizontalAlignment: Alignment.Horizontal = Alignment.Start,            // the horizontal alignment applied to the items.\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),      // logic describing fling behavior.\n    userScrollEnabled: Boolean = true,                                      // whether the scrolling via the user gestures or accessibility actions is allowed. \n    content: LazyListScope.() -\u003e Unit                                       // a block which describes the content \n)\n\n// Example\nLazyColumn(\n     contentPadding = PaddingValues(16.dp),\n     verticalArrangement = Arrangement.spacedBy(6.dp),\n     modifier = modifier.fillMaxSize().wrapContentHeight()\n) {\n        // items is a DSL available in the LazyColumn scope. This allows you to render a composable\n        // for a single element in the list.\n        items(list.size) {\n            ListItem(item = list[it], onClick = { listModel -\u003e\n                Toast.makeText(context, listModel.name +  \" clicked!\", Toast.LENGTH_SHORT).show()\n            })\n        }\n}\n```\n\n| Example                                                                               | Preview                                                                                           |\n|---------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|\n| [ListScreen](app/src/main/java/com/an/jetpackcomposesample/screen/list/ListScreen.kt) | \u003cimg src =\"media/list/img_list_1.png\" width=300\u003e\u003cimg src =\"/media/list/img_list_2.png\" width=300\u003e |\n\n### Scaffold\nThe `Scaffold` composable provides a straightforward API you can use to quickly assemble your app's structure according to Material Design guidelines. `Scaffold` accepts several composables as parameters.\n```\n@Composable\nfun Scaffold(\n    modifier: Modifier = Modifier,                              // the modifier to apply to this layout. \n    topBar: @Composable () -\u003e Unit = {},                        // top app bar of the screen\n    bottomBar: @Composable () -\u003e Unit = {},                     // bottom bar of the screen\n    snackbarHost: @Composable () -\u003e Unit = {},                  // component to host Snackbars that are pushed to be shown via SnackbarHostState.showSnackbar\n    floatingActionButton: @Composable () -\u003e Unit = {},              // Main action button of the screen\n    floatingActionButtonPosition: FabPosition = FabPosition.End,        // position of the FAB on the screen\n    containerColor: Color = MaterialTheme.colorScheme.background,       // the color used for the background of this scaffold.\n    contentColor: Color = contentColorFor(containerColor),              // the preferred color for content inside this scaffold.\n    contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,       // window insets to be passed to content slot via PaddingValues params.\n    content: @Composable (PaddingValues) -\u003e Unit                // content of the screen\n)\n    \n// Example\nScaffold(\n        bottomBar = {\n            BottomAppBar(\n                containerColor = MaterialTheme.colorScheme.primaryContainer,\n                contentColor = MaterialTheme.colorScheme.primary,\n            ) {\n                Text(\n                    modifier = Modifier.fillMaxWidth(),\n                    textAlign = TextAlign.Center,\n                    text = \"Bottom app bar\",\n                )\n            }\n        },\n        floatingActionButton = {\n            FloatingActionButton(\n                containerColor = MaterialTheme.colorScheme.primaryContainer,\n                contentColor = MaterialTheme.colorScheme.primary,\n                onClick = { Toast.makeText(context, \"Clicked!\", Toast.LENGTH_SHORT).show() }\n            ) {\n                Icon(Icons.Default.Add, contentDescription = \"Add\")\n            }\n        }\n)    \n```\n\n| Example                                                                                  | Preview                                                                                                           |\n|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|\n| [ScaffoldScreen](app/src/main/java/com/an/jetpackcomposesample/screen/ScaffoldScreen.kt) | \u003cimg src =\"media/scaffold/img_scaffold_1.png\" width=300\u003e\u003cimg src =\"/media/scaffold/img_scaffold_2.png\" width=300\u003e |\n\n\n### Card\n`Card` composable is a predefined composable that is meant to represent the card surface as specified by the Material Design specification. We also configure it to have rounded corners and apply a modifier. Attributes of `Card` composable includes:\n```\n@Composable\nfun Card(\n    modifier: Modifier = Modifier,                    // the Modifier to be applied to this card\n    shape: Shape = CardDefaults.shape,                // defines the shape of this card's container, border (when border is not null), and shadow (when using elevation)\n    colors: CardColors = CardDefaults.cardColors(),    //  CardColors that will be used to resolve the colors used for this card in different states.\n    elevation: CardElevation = CardDefaults.cardElevation(),        // This controls the size of the shadow below the card.\n    border: BorderStroke? = null,                      // the border to draw around the container of this card  \n    content: @Composable ColumnScope.() -\u003e Unit        // define content of the card\n)\n\n// Example\nCard(\n    elevation = CardDefaults.cardElevation(8.dp),\n    modifier = paddingModifier\n            .fillMaxWidth()\n            .height(120.dp)\n    ) {\n        Text(text = \"Simple Card \",\n            modifier = paddingModifier)\n    }\n}\n```\n\n| Example                                                                          | Preview                                                                                           |\n|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|\n| [CardScreen](app/src/main/java/com/an/jetpackcomposesample/screen/CardScreen.kt) | \u003cimg src =\"media/card/img_card_1.png\" width=300\u003e\u003cimg src =\"/media/card/img_card_2.png\" width=300\u003e |\n\n### Progress Indicators\nProgress indicators visually surface the status of an operation. They use motion to bring to the user's attention how near completion the process is, such as loading or processing data. There are 2 types of Progress indicators: `LinearProgressIndicator` \u0026 `CircularProgressIndicator`. Attributes of `LinearProgressIndicator` includes:\n```\n@Composable\nfun LinearProgressIndicator(\n    modifier: Modifier = Modifier,                                         // the Modifier to be applied to this progress indicator\n    color: Color = ProgressIndicatorDefaults.linearColor,                 // color of this progress indicator \n    trackColor: Color = ProgressIndicatorDefaults.linearTrackColor,        // color of the track behind the indicator, visible when the progress has not reached the area of the overall indicator yet\n    strokeCap: StrokeCap = ProgressIndicatorDefaults.LinearStrokeCap,      // stroke cap to use for the ends of this progress indicator\n)\n\n// Example of LinearProgressIndicator\nLinearProgressIndicator(\n        modifier = Modifier.fillMaxWidth().height(8.dp),\n        trackColor = MaterialTheme.colorScheme.secondaryContainer,\n        color = MaterialTheme.colorScheme.primary, //progress color\n    )\n}\n\n// Example of CircularProgressIndicator\nCircularProgressIndicator(\n        trackColor = MaterialTheme.colorScheme.primary,\n        color = MaterialTheme.colorScheme.secondaryContainer //progress color\n)\n```\n\n| Example                                                                                        | Preview                                                                                                           |\n|------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|\n| [ProgressBarScreen](app/src/main/java/com/an/jetpackcomposesample/screen/ProgressBarScreen.kt) | \u003cimg src =\"media/progress/img_progress_1.png\" width=300\u003e\u003cimg src =\"/media/progress/img_progress_2.png\" width=300\u003e |\n\n### Alert Dialog\nThe `AlertDialog` composable provides a convenient API for creating a Material Design themed dialog. `AlertDialog` has specific parameters for handling particular elements of the dialog.\n```\n@Composable\nfun AlertDialog(\n    onDismissRequest: () -\u003e Unit,               // called when the user tries to dismiss the Dialog by clicking outside or pressing the back button. This is not called when the dismiss button is clicked.\n    confirmButton: @Composable () -\u003e Unit,      // button which is meant to confirm a proposed action\n    modifier: Modifier = Modifier,              // the Modifier to be applied to this dialog\n    dismissButton: @Composable (() -\u003e Unit)? = null,        // button which is meant to dismiss the dialog\n    icon: @Composable (() -\u003e Unit)? = null,     // optional icon that will appear above the title or above the text.\n    title: @Composable (() -\u003e Unit)? = null,    // title which should specify the purpose of the dialog.\n    text: @Composable (() -\u003e Unit)? = null,     // text which presents the details regarding the dialog's purpose.\n    shape: Shape = AlertDialogDefaults.shape,   // defines the shape of this dialog's container\n    containerColor: Color = AlertDialogDefaults.containerColor,         // the color used for the background of this dialog.\n    iconContentColor: Color = AlertDialogDefaults.iconContentColor,     // the content color used for the icon.\n    titleContentColor: Color = AlertDialogDefaults.titleContentColor,   // the content color used for the title.\n    textContentColor: Color = AlertDialogDefaults.textContentColor,     // the content color used for the text.\n    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,            // when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container.\n    properties: DialogProperties = DialogProperties()               // typically platform specific properties to further configure the dialog.\n)\n\n\n// Example of AlertDialog\nAlertDialog(\n        icon = {\n            Icon(Icons.Filled.Info, contentDescription = \"Info Icon\", tint = MaterialTheme.colorScheme.secondaryContainer)\n        },\n        title = {\n            Text(text = \"Dialog with info icon\")\n        },\n        text = {\n            Text(text = \"The Dialog component displays pop up messages or requests user input on a layer above the main app content. It creates an interruptive UI experience to capture user attention.\")\n        },\n        onDismissRequest = { },\n        confirmButton = {\n            TextButton(\n                onClick = { showAlertDialog.value = false }\n            ) {\n                Text(\"Confirm\", color = MaterialTheme.colorScheme.primary)\n            }\n        },\n        dismissButton = {\n            TextButton(\n                onClick = { showAlertDialog.value = false }\n            ) {\n                Text(\"Dismiss\", color = MaterialTheme.colorScheme.primary)\n            }\n        }\n)\n```\n\n| Example                                                                              | Preview                                                                                                                         |\n|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|\n| [DialogScreen](app/src/main/java/com/an/jetpackcomposesample/screen/DialogScreen.kt) | \u003cimg src =\"media/alertdialog/img_alert_dialog_1.png\" width=300\u003e\u003cimg src =\"/media/alertdialog/img_alert_dialog_2.png\" width=300\u003e |\n\n### Custom Dialog\n`Dialog` is a basic composable that doesn't provide any styling or predefined slots for content. It is a relatively straightforward container that you should populate with a container such as `Card`.\n```\n@Composable\nfun Dialog(\n    onDismissRequest: () -\u003e Unit,                       // Executes when the user tries to dismiss the dialog.\n    properties: DialogProperties = DialogProperties(),  // for further customization of this dialog's behavior.\n    content: @Composable () -\u003e Unit                     // The content to be displayed inside the dialog.\n)\n\n// Example of Dialog\nDialog(onDismissRequest = { showCustomDialog.value = false }) {\n    Card(\n          elevation = CardDefaults.cardElevation(8.dp),\n          shape = RoundedCornerShape(8.dp),\n          modifier = Modifier\n                .fillMaxWidth()\n                .padding(bottom = 20.dp, top = 20.dp)\n    ) {\n         Column(\n             horizontalAlignment = Alignment.CenterHorizontally,\n             modifier = Modifier.fillMaxWidth().wrapContentHeight()\n                    .background(MaterialTheme.colorScheme.inverseOnSurface)\n                    .padding(16.dp)\n            ) {\n                Icon(Icons.Filled.Info, contentDescription = \"Info Icon\", tint = MaterialTheme.colorScheme.secondaryContainer)\n                    Column(modifier = Modifier.padding(16.dp).fillMaxWidth(),\n                        verticalArrangement = Arrangement.Center,\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                ) {\n                 Text(\n                        text = \"Dialog with info icon\",\n                        style = TextStyle(fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.primary, fontSize = 18.sp)\n                    )\n                 Text(\n                        modifier = Modifier.padding(top = 10.dp),\n                        textAlign = TextAlign.Center,\n                        text = \"This Dialog is an example of a custom dialog with the Dialog Composable\"\n                    )\n                }\n                TextButton(\n                    onClick = { showCustomDialog.value = false }\n                ) {\n                    Text(\"Confirm\", color = MaterialTheme.colorScheme.primary)\n                }\n                TextButton(\n                    onClick = { showCustomDialog.value = false }\n                ) {\n                    Text(\"Dismiss\", color = MaterialTheme.colorScheme.primary)\n                }\n            }\n     }\n }\n```\n\n| Example                                                                              | Preview                                                                                                                             |\n|--------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|\n| [DialogScreen](app/src/main/java/com/an/jetpackcomposesample/screen/DialogScreen.kt) | \u003cimg src =\"media/customdialog/img_custom_dialog_1.png\" width=300\u003e\u003cimg src =\"/media/customdialog/img_custom_dialog_2.png\" width=300\u003e |\n\n## DatePicker Dialog\nThe `DatePicker` composable is designed to display a full-screen view of the `DatePicker`. It offers a range of features, including date validation, which allows you to disable future dates or implement custom logic based on your requirements. To enable date validation, you’ll need to provide your own implementation of the SelectableDates interface. We can use the `DatePickerDialog` composable to create a wrapper around `DatePicker` where you can pass your own **Ok** button, **Cancel** button composables.\n\n```\n@Composable\nfun DatePickerDialog(\n    onDismissRequest: () -\u003e Unit,\n    confirmButton: @Composable () -\u003e Unit,\n    modifier: Modifier = Modifier,\n    dismissButton: @Composable (() -\u003e Unit)? = null,\n    shape: Shape = DatePickerDefaults.shape,\n    tonalElevation: Dp = DatePickerDefaults.TonalElevation,\n    colors: DatePickerColors = DatePickerDefaults.colors(),\n    properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false),\n    content: @Composable ColumnScope.() -\u003e Unit\n)\n\n// Example of DatePickerDialog\nDatePickerDialog(\n    onDismissRequest = { showDatePickerDialog.value = false },\n    confirmButton = {\n          TextButton(\n                onClick = { showDatePickerDialog.value = false }\n            ) {\n                Text(\"Confirm\", color = MaterialTheme.colorScheme.primary)\n            }\n    },\n    dismissButton = {\n          TextButton(\n                onClick = { showDatePickerDialog.value = false }\n          ) {\n                Text(text = \"Cancel\", color = MaterialTheme.colorScheme.primary)\n          }\n    }) {\n    DatePicker(\n          state = dateState,\n          showModeToggle = true\n    )\n}\n```\n\n| Example                                                                              | Preview                                                                                                                   |\n|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|\n| [DialogScreen](app/src/main/java/com/an/jetpackcomposesample/screen/DialogScreen.kt) | \u003cimg src =\"media/datepicker/img_datepicker_1.png\" width=300\u003e\u003cimg src =\"/media/datepicker/img_datepicker_2.png\" width=300\u003e |\n\n### BottomSheet\nModal bottom sheets are used as an alternative to inline menus or simple dialogs on mobile, especially when offering a long list of action items, or when items require longer descriptions and icons. Like dialogs, modal bottom sheets appear in front of app content, disabling all other app functionality when they appear, and remaining on screen until confirmed, dismissed, or a required action has been taken.\n```\n@Composable\n@ExperimentalMaterial3Api\nfun ModalBottomSheet(\n    onDismissRequest: () -\u003e Unit,                                       // Executes when the user clicks outside of the bottom sheet   \n    modifier: Modifier = Modifier,                                      // Optional Modifier for the bottom sheet\n    sheetState: SheetState = rememberModalBottomSheetState(),               // The state of the bottom sheet.\n    sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth,                  // defines what the maximum width the sheet will take.\n    shape: Shape = BottomSheetDefaults.ExpandedShape,                       // The shape of the bottom sheet\n    containerColor: Color = BottomSheetDefaults.ContainerColor,             // The color used for the background of this bottom sheet\n    contentColor: Color = contentColorFor(containerColor),                  // The preferred color for content inside this bottom sheet\n    tonalElevation: Dp = BottomSheetDefaults.Elevation,                     // The tonal elevation of this bottom sheet.\n    scrimColor: Color = BottomSheetDefaults.ScrimColor,                             // Color of the scrim that obscures content when the bottom sheet is open.\n    dragHandle: @Composable (() -\u003e Unit)? = { BottomSheetDefaults.DragHandle() },       // Optional visual marker to swipe the bottom sheet\n    windowInsets: WindowInsets = BottomSheetDefaults.windowInsets,                      // window insets to be passed to the bottom sheet window\n    properties: ModalBottomSheetProperties = ModalBottomSheetDefaults.properties(),     // for further customization of this modal bottom sheet's behavior.    \n    content: @Composable ColumnScope.() -\u003e Unit,                                        // The content to be displayed inside the bottom sheet.\n)\n\n// Example of BottomSheet\nval modalBottomSheetState = rememberModalBottomSheetState()\n\nModalBottomSheet(\n        onDismissRequest = { showBottomSheet.value = false },\n        sheetState = modalBottomSheetState,\n        dragHandle = { BottomSheetDefaults.DragHandle() },\n) {\n    LazyColumn {\n        items(countries.size) {\n            Row(modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp, horizontal = 20.dp)\n                clickable {\n                      Toast.makeText(context, countries[it].first+ \" Clicked\", Toast.LENGTH_SHORT).show()\n                      showBottomSheet.value = false\n                  }\n                ) {\n                Text(\n                    text = countries[it].second,\n                    modifier = Modifier.padding(end = 20.dp, top = 5.dp, bottom = 5.dp)\n                )\n               Text(text = countries[it].first)\n            }\n        }\n    }\n}\n```\n\n| Example                                                                              | Preview                                                                                                                       |\n|--------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|\n| [DialogScreen](app/src/main/java/com/an/jetpackcomposesample/screen/DialogScreen.kt) | \u003cimg src =\"media/bottomsheet/img_bottomsheet_1.png\" width=300\u003e\u003cimg src =\"/media/bottomsheet/img_bottomsheet_2.png\" width=300\u003e |\n\n### RadioButton\nRadio buttons allow users to select one option from a set. RadioButton can be combined together with `Text` in the desired layout to achieve radio group-like behaviour, where the entire layout is selectable. Attributes of `RadioButton` composable include:\n```\n@Composable\nfun RadioButton(\n    selected: Boolean,                                      // whether this radio button is selected or not\n    onClick: (() -\u003e Unit)?,                                 // called when this radio button is clicked.\n    modifier: Modifier = Modifier,                          // modifier of the radio button\n    enabled: Boolean = true,                                // controls the enabled state of this radio button.\n    colors: RadioButtonColors = RadioButtonDefaults.colors(),           // RadioButtonColors that will be used to resolve the color used for this radio button in different states\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n)\n\n// Example\nRadioButton(\n      selected = (country == selectedOption),\n      onClick = { selectedOption = country },\n      colors = RadioButtonDefaults.colors(\n                  selectedColor = MaterialTheme.colorScheme.primary,\n                  unselectedColor = MaterialTheme.colorScheme.secondaryContainer\n          )\n      )\n      Text(\n           text = country,\n           style = MaterialTheme.typography.bodyLarge\n      )\n)\n```\n\n| Example                                                                                        | Preview                                                                                               |\n|------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|\n| [RadioButtonScreen](app/src/main/java/com/an/jetpackcomposesample/screen/RadioButtonScreen.kt) | \u003cimg src =\"media/radio/img_radio_1.png\" width=300\u003e\u003cimg src =\"/media/radio/img_radio_2.png\" width=300\u003e |\n\n\n### CheckBox\nCheckboxes allow users to select one or more items from a set. Checkboxes can turn an option on or off. Attributes of `CheckBox` include:\n```\n@Composable\nfun Checkbox(\n    checked: Boolean,                                   // whether this checkbox is checked or unchecked\n    onCheckedChange: ((Boolean) -\u003e Unit)?,              // called when this checkbox is clicked.        \n    modifier: Modifier = Modifier,                      // modifier of the checkbox    \n    enabled: Boolean = true,                            // controls the enabled state of this checkbox.\n    colors: CheckboxColors = CheckboxDefaults.colors(),         // CheckboxColors that will be used to resolve the colors used for this checkbox in different states\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n)\n\n// Example\nCheckbox(\n    checked = (country == checkedOption ),\n    onCheckedChange = { checkedOption = country },\n    colors = CheckboxDefaults.colors(\n              checkedColor = MaterialTheme.colorScheme.secondaryContainer,\n              uncheckedColor = MaterialTheme.colorScheme.primary\n    )\n)\n```\n\n| Example                                                                                  | Preview                                                                                                           |\n|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|\n| [CheckBoxScreen](app/src/main/java/com/an/jetpackcomposesample/screen/CheckBoxScreen.kt) | \u003cimg src =\"media/checkbox/img_checkbox_1.png\" width=300\u003e\u003cimg src =\"/media/checkbox/img_checkbox_2.png\" width=300\u003e |\n\n### Slider\nSliders allow users to make selections from a range of values. Sliders reflect a range of values along a bar, from which users may select a single value. They are ideal for adjusting settings such as volume, brightness, or applying image filters. Attributes of `Slider` includes:\n```\n@Composable\nfun Slider(\n    value: Float,                                           // current value of the slider.\n    onValueChange: (Float) -\u003e Unit,                         // callback in which value should be updated    \n    modifier: Modifier = Modifier,                          // the Modifier to be applied to this slider\n    enabled: Boolean = true,                                // controls the enabled state of this slider\n    valueRange: ClosedFloatingPointRange\u003cFloat\u003e = 0f..1f,       // range of values that this slider can take.\n    @IntRange(from = 0)                                         // range of values that this slider can take. \n    steps: Int = 0,                                         // if greater than 0, specifies the amount of discrete allowable values, evenly distributed across the whole value range. \n    onValueChangeFinished: (() -\u003e Unit)? = null,            // called when value change has ended\n    colors: SliderColors = SliderDefaults.colors(),         // SliderColors that will be used to resolve the colors used for this slider in different states\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n)\n\n// Example\nSlider(\n     value = sliderPosition,\n     onValueChange = { sliderPosition = it },\n     colors = SliderDefaults.colors(\n           thumbColor = MaterialTheme.colorScheme.primary,\n           activeTrackColor = MaterialTheme.colorScheme.primary,\n           inactiveTrackColor = MaterialTheme.colorScheme.secondaryContainer,\n      ),\n      steps = 5,\n      valueRange = 0f..100f\n)\n```\n| Example                                                                                                  | Preview                                                                                                   |\n|----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|\n| [SmallerComponentScreen](app/src/main/java/com/an/jetpackcomposesample/screen/SmallerComponentScreen.kt) | \u003cimg src =\"media/slider/img_slider_1.png\" width=300\u003e\u003cimg src =\"/media/slider/img_slider_2.png\" width=300\u003e |\n\n### Switch\nA pre-defined composable that's capable of rendering a switch.\n```\n@Composable\nfun Switch(\n    checked: Boolean,                                   // whether or not this switch is checked\n    onCheckedChange: ((Boolean) -\u003e Unit)?,              // called when this switch is clicked\n    modifier: Modifier = Modifier,                      // the Modifier to be applied to this switch\n    thumbContent: (@Composable () -\u003e Unit)? = null,        // content that will be drawn inside the thumb \n    enabled: Boolean = true,                            // controls the enabled state of this switch\n    colors: SwitchColors = SwitchDefaults.colors(),         // SwitchColors that will be used to resolve the colors used for this switch in different states\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n)\n\n// Example\nvar checked by remember { mutableStateOf(true) }\nSwitch(\n       checked = checked,\n       onCheckedChange = { checked = it },\n       thumbContent = if (checked) {\n      {\n             Icon(\n                  imageVector = Icons.Filled.Check,\n                  contentDescription = null,\n                  modifier = Modifier.size(SwitchDefaults.IconSize),\n             )\n       }\n    } else {\n             null\n    }\n)\n```\n\n| Example                                                                                                  | Preview                                                                                                   |\n|----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|\n| [SmallerComponentScreen](app/src/main/java/com/an/jetpackcomposesample/screen/SmallerComponentScreen.kt) | \u003cimg src =\"media/slider/img_slider_1.png\" width=300\u003e\u003cimg src =\"/media/slider/img_slider_2.png\" width=300\u003e |\n\n### Chips\nChips help people enter information, make selections, filter content, or trigger actions. Chips can show multiple interactive elements together in the same area, such as a list of selectable movie times, or a series of email contacts. The four types of chips and where you might use them are as follows:\n- Assist: Guides the user during a task. Often appears as a temporary UI element in response to user input.\n- Filter: Allows users to refine content from a set of options. They can be selected or deselected, and may include a checkmark icon when selected.\n- Input: Represents user-provided information, such as selections in a menu. They can contain an icon and text, and provide an 'X' for removal.\n- Suggestion: Provides recommendations to the user based on their recent activity or input. Typically appear beneath an input field to prompt user actions.\n  These components share the following attributes:\n\n```\n@Composable\nprivate fun Chip(\n    modifier: Modifier,\n    onClick: () -\u003e Unit,\n    enabled: Boolean,\n    label: @Composable () -\u003e Unit,\n    labelTextStyle: TextStyle,\n    labelColor: Color,\n    leadingIcon: @Composable (() -\u003e Unit)?,\n    trailingIcon: @Composable (() -\u003e Unit)?,\n    shape: Shape,\n    colors: ChipColors,\n    elevation: ChipElevation?,\n    border: BorderStroke?,\n    minHeight: Dp,\n    paddingValues: PaddingValues,\n    interactionSource: MutableInteractionSource,\n)\n\n// AssisChip example\nAssistChip(\n   onClick = {  },\n   label = {\n      Text(text = \"Assist chip\", style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary)\n   },\n   border = BorderStroke(width = 3.dp, color = MaterialTheme.colorScheme.primary),\n   leadingIcon = {\n            Icon(Icons.Filled.Settings, contentDescription = \"Settings\", Modifier.size(AssistChipDefaults.IconSize), tint = MaterialTheme.colorScheme.primary)\n   }\n)\n\n// FilterChip example\nFilterChip(\n    onClick = { selectedFilter = !selectedFilter },\n    border = FilterChipDefaults.filterChipBorder(\n       enabled = true,\n       selected = false,\n       borderColor = MaterialTheme.colorScheme.primary,\n       selectedBorderColor = MaterialTheme.colorScheme.secondaryContainer\n    ),\n    colors = FilterChipDefaults.filterChipColors(selectedContainerColor = MaterialTheme.colorScheme.secondaryContainer),\n    label = {\n            Text(text = \"Filter chip\", style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary)\n    },\n    selected = selectedFilter,\n    leadingIcon = {\n            Icon(imageVector = filterLeadingIcon, contentDescription = \"Leading icon\", modifier = Modifier.size(FilterChipDefaults.IconSize), tint = MaterialTheme.colorScheme.primary)\n    },\n)\n\n// InputChip example\nInputChip(\n   onClick = {  },\n   label = {\n            Text(text = \"Input chip\", style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary)\n   },\n    border = FilterChipDefaults.filterChipBorder(\n         enabled = true,\n         selected = false,\n         borderColor = MaterialTheme.colorScheme.primary,\n         selectedBorderColor = MaterialTheme.colorScheme.secondaryContainer\n    ),\n    colors = FilterChipDefaults.filterChipColors(selectedContainerColor = MaterialTheme.colorScheme.secondaryContainer),\n    selected = enabled,\n    avatar = {\n            Icon(Icons.Filled.Person, contentDescription = \"Input Chip person icon\", Modifier.size(InputChipDefaults.AvatarSize), tint = MaterialTheme.colorScheme.primary)\n    },\n    trailingIcon = {\n            Icon(Icons.Default.Close, contentDescription = \"Input Chip close icon\", Modifier.size(InputChipDefaults.AvatarSize), tint = MaterialTheme.colorScheme.primary)\n     },\n)\n\n// SuggestionChip example\nSuggestionChip(\n    onClick = { Toast.makeText(context, \"Suggestion clicked!\", Toast.LENGTH_SHORT).show() },\n    border = BorderStroke(width = 3.dp, color = MaterialTheme.colorScheme.primary),\n    label = {\n          Text(text = \"Suggestion chip\", style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary)\n    }\n)\n```\n\n| Example                                                                                                  | Preview                                                                                                   |\n|----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|\n| [SmallerComponentScreen](app/src/main/java/com/an/jetpackcomposesample/screen/SmallerComponentScreen.kt) | \u003cimg src =\"media/slider/img_slider_1.png\" width=300\u003e\u003cimg src =\"/media/slider/img_slider_2.png\" width=300\u003e |\n\n### Tabs\nTab layouts are a common navigation component in mobile app development. We can use the `TabRow` composable to create Tabs and `ScrollableTabRow` for scrollable tabs. Attributes of `TabRow` include:\n```\n@Composable\nfun ScrollableTabRow(\n    selectedTabIndex: Int,                          // the index of the currently selected tab\n    modifier: Modifier = Modifier,                  // the Modifier to be applied to this tab row\n    containerColor: Color = TabRowDefaults.primaryContainerColor,       // the color used for the background of this tab row\n    contentColor: Color = TabRowDefaults.primaryContentColor,           // the preferred color for content inside this tab row\n    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,              // the padding between the starting and ending edge of the scrollable tab row, and the tabs inside the row\n    indicator: @Composable (tabPositions: List\u003cTabPosition\u003e) -\u003e Unit = @Composable { tabPositions -\u003e            // the indicator that represents which tab is currently selected.\n        TabRowDefaults.SecondaryIndicator(\n            Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])\n        )\n    },\n    divider: @Composable () -\u003e Unit = @Composable {                 // the divider displayed at the bottom of the tab row\n        HorizontalDivider()\n    },\n    tabs: @Composable () -\u003e Unit                        // the tabs inside this tab row\n)\n\n// Example\nScrollableTabRow(\n  selectedTabIndex = pagerState.currentPage,\n  edgePadding = 0.dp, // removes padding between the first pager item\n  divider = { Spacer(modifier = Modifier.height(5.dp)) },\n  containerColor = MaterialTheme.colorScheme.primaryContainer,\n  indicator = { tabPositions -\u003e\n            // we are specifying the styling for tab indicator by specifying color for the selected tab indicator\n            if (pagerState.currentPage \u003c tabPositions.size) {\n                SecondaryIndicator(\n                    modifier = Modifier.tabIndicatorOffset(tabPositions[pagerState.currentPage]),\n                    color = MaterialTheme.colorScheme.primary\n                )\n            }\n  },\n  tabs = {\n            tabData.forEachIndexed { index, data -\u003e\n                Tab(\n                    onClick = {\n                        scope.launch {\n                            pagerState.animateScrollToPage(index)\n                        }\n                    },\n                    selected = pagerState.currentPage == index,\n                    icon = {\n                        Icon(\n                            imageVector = data.second,\n                            contentDescription = \"Tab layout icon\"\n                        )\n                    },\n                    unselectedContentColor = MaterialTheme.colorScheme.outline,\n                    selectedContentColor = MaterialTheme.colorScheme.primary,\n\n                    // Uncomment if you don't want Text to the tab\n                    text = {\n                        Text(text = data.first, fontSize = 12.sp)\n                    }\n                )\n            }\n        },\n        modifier = Modifier.fillMaxWidth().wrapContentHeight()\n)\n```\n\n| Example                                                                                     | Preview                                                                                           |\n|---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|\n| [MainTabScreen](app/src/main/java/com/an/jetpackcomposesample/screen/tabs/MainTabScreen.kt) | \u003cimg src =\"media/tabs/img_tabs_1.gif\" width=300\u003e\u003cimg src =\"/media/tabs/img_tabs_2.gif\" width=300\u003e |\n\n### Bottom Navigation Bar\nNavigation bars offer a persistent and convenient way to switch between primary destinations in an app. The recommended configuration for a `NavigationBarItem` depends on how many items there are inside a `NavigationBar`:\n```\n@Composable\nfun NavigationBar(\n    modifier: Modifier = Modifier,                  // the Modifier to be applied to this navigation bar \n    containerColor: Color = NavigationBarDefaults.containerColor,                           // the color used for the background of this navigation bar\n    contentColor: Color = MaterialTheme.colorScheme.contentColorFor(containerColor),        // the preferred color for content inside this navigation bar\n    tonalElevation: Dp = NavigationBarDefaults.Elevation,                                   // when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container.\n    windowInsets: WindowInsets = NavigationBarDefaults.windowInsets,                    // a window insets of the navigation bar\n    content: @Composable RowScope.() -\u003e Unit                    // the content of this navigation bar, typically 3-5 NavigationBarItems\n)\n\n@Composable\nfun RowScope.NavigationBarItem(\n    selected: Boolean,                      // whether this item is selected\n    onClick: () -\u003e Unit,                    // called when this item is clicked\n    icon: @Composable () -\u003e Unit,           // icon for this item\n    modifier: Modifier = Modifier,          // the Modifier to be applied to this item\n    enabled: Boolean = true,                // controls the enabled state of this item\n    label: @Composable (() -\u003e Unit)? = null,        // optional text label for this item\n    alwaysShowLabel: Boolean = true,                // whether to always show the label for this item\n    colors: NavigationBarItemColors = NavigationBarItemDefaults.colors(),           // NavigationBarItemColors that will be used to resolve the colors used for this item in different states\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n) \n```\n\n| Example                                                                                                      | Preview                                                                                                               |\n|--------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|\n| [MainBottomBarScreen](app/src/main/java/com/an/jetpackcomposesample/screen/bottombar/MainBottomBarScreen.kt) | \u003cimg src =\"media/bottombar/img_bottombar_1.gif\" width=300\u003e\u003cimg src =\"/media/bottombar/img_bottombar_2.gif\" width=300\u003e |\n\n### Dynamic themes\nDynamic Color, which was added in Android 12, enables users to personalize their devices to align tonally with the color scheme of their personal wallpaper or through a selected color in the wallpaper picker.  We can leverage this feature by adding the `DynamicColors` API, which applies this theming to our app to make it more personalized to the user. More details can be found [here](https://developer.android.com/develop/ui/views/theming/dynamic-colors).\n\n| Example                                                                                          | Preview                                                                                                                                                                                                                                                                                                         |\n|--------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [DynamicThemeScreen](app/src/main/java/com/an/jetpackcomposesample/screen/DynamicThemeScreen.kt) | \u003cimg src =\"media/theme/img_theme_1.png\" width=300\u003e\u003cimg src =\"/media/theme/img_theme_2.png\" width=300\u003e\u003cimg src =\"media/theme/img_theme_3.png\" width=300\u003e\u003cimg src =\"/media/theme/img_theme_4.png\" width=300\u003e\u003cimg src =\"media/theme/img_theme_5.png\" width=300\u003e\u003cimg src =\"/media/theme/img_theme_6.png\" width=300\u003e |\n\n### Switching between dark mode and light mode\n\u003cimg src =\"media/img_dark_mode.gif\" width=300\u003e\n\n### Navigation in Compose\n[Navigation](https://developer.android.com/develop/ui/compose/navigation) helps you in understanding how your app moves across different components in your Application. The Navigation Component is made up of three major parts:\n- Navigation Graph: This is a resource that collects all navigation-related data in one place.\n- `NavHost`: This is a unique composable that you can include in your layout. It shows various destinations from your Navigation Graph. The NavHost links the NavController with a navigation graph that specifies the composable destinations that you should be able to navigate between.\n- `NavController`: The NavController is the central API for the Navigation component. It is stateful and keeps track of the back stack of composables that make up the screens in your app and the state of each screen. You can create a `NavController` by using the `rememberNavController()` method in your composable.\n\n##### Setup Navigation graph \u0026 NavHost\n- Define screens name and routes for Navigation in one file. ie. [NavigationItem.kt](https://github.com/anitaa1990/JetpackComposeSample/blob/master/app/src/main/java/com/an/jetpackcomposesample/provider/NavigationItem.kt)\n- Define NavHost with your screens. ie. [Navigation.kt](https://github.com/anitaa1990/JetpackComposeSample/blob/master/app/src/main/java/com/an/jetpackcomposesample/provider/Navigation.kt)\n- Call `Navigation.kt` inside the `MainApp` file.\n```\nNavigation(\n      navController = navController,\n      modifier = Modifier.padding(innerPadding)\n)\n```\n\nLicense\n-----------------\n\n    Copyright 2024 Anitaa Murthy\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanitaa1990%2Fjetpackcomposesample","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanitaa1990%2Fjetpackcomposesample","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanitaa1990%2Fjetpackcomposesample/lists"}