├── .gitignore ├── .idea ├── .gitignore ├── .name ├── compiler.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── kotlinc.xml └── misc.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── material3components │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── material3components │ │ │ ├── BadgeM3.kt │ │ │ ├── BottomAppBarM3.kt │ │ │ ├── BottomSheetM3.kt │ │ │ ├── CheckboxM3.kt │ │ │ ├── ChipsM3.kt │ │ │ ├── DialogM3.kt │ │ │ ├── FABM3.kt │ │ │ ├── ListsM3.kt │ │ │ ├── MainActivity.kt │ │ │ ├── MenuM3.kt │ │ │ ├── NavigationBarM3.kt │ │ │ ├── NavigationDrawerM3.kt │ │ │ ├── ProgressIndicatorsM3.kt │ │ │ ├── RadioButtonM3.kt │ │ │ ├── SearchBarM3.kt │ │ │ ├── SliderM3.kt │ │ │ ├── SnackbarM3.kt │ │ │ ├── SwitchM3.kt │ │ │ ├── TextFieldsM3.kt │ │ │ ├── TopAppBarM3.kt │ │ │ └── ui │ │ │ └── theme │ │ │ ├── Color.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_launcher_background.xml │ │ ├── ic_visibility.xml │ │ └── ic_visibility_off.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ └── data_extraction_rules.xml │ └── test │ └── java │ └── com │ └── example │ └── material3components │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | Material 3 Components -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 32 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Material Design 3 Components 2 | 3 | Welcome to the **Material3 Components** repository! This repository is dedicated to showcasing various components of Material Design 3 using Jetpack Compose. 4 | 5 | ## YouTube Playlist 6 | 7 | To complement this repository, we have also created a detailed YouTube playlist where each component of Material Design 3 is explained in depth. 8 | 9 | 🎥 [Material Design 3 Components with Jetpack Compose](https://youtube.com/playlist?list=PL1b73-6UjePAGw5BsVvHzPXTHTWhh6cXi) 10 | 11 | ![Screenshot (159)](https://github.com/CodeInKotLang/Material_3_Components/assets/110901093/47584831-e773-4259-ac0c-e11420567e62) 12 | 13 | 14 | ## Support 15 | 16 | If you find the content valuable, consider [buying me a coffee](https://ko-fi.com/mohammadarif) to support the creation of more content. 17 | 18 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | } 5 | 6 | android { 7 | namespace 'com.example.material3components' 8 | compileSdk 33 9 | 10 | defaultConfig { 11 | applicationId "com.example.material3components" 12 | minSdk 21 13 | targetSdk 33 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | vectorDrawables { 19 | useSupportLibrary true 20 | } 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_17 31 | targetCompatibility JavaVersion.VERSION_17 32 | } 33 | kotlinOptions { 34 | jvmTarget = '17' 35 | } 36 | buildFeatures { 37 | compose true 38 | } 39 | composeOptions { 40 | kotlinCompilerExtensionVersion '1.4.7' 41 | } 42 | packagingOptions { 43 | resources { 44 | excludes += '/META-INF/{AL2.0,LGPL2.1}' 45 | } 46 | } 47 | } 48 | 49 | dependencies { 50 | 51 | implementation 'androidx.core:core-ktx:1.8.0' 52 | implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0') 53 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' 54 | implementation 'androidx.activity:activity-compose:1.5.1' 55 | implementation platform('androidx.compose:compose-bom:2022.10.00') 56 | implementation 'androidx.compose.ui:ui' 57 | implementation 'androidx.compose.ui:ui-graphics' 58 | implementation 'androidx.compose.ui:ui-tooling-preview' 59 | implementation 'androidx.compose.material3:material3:1.1.1' 60 | testImplementation 'junit:junit:4.13.2' 61 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 62 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 63 | androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00') 64 | androidTestImplementation 'androidx.compose.ui:ui-test-junit4' 65 | debugImplementation 'androidx.compose.ui:ui-tooling' 66 | debugImplementation 'androidx.compose.ui:ui-test-manifest' 67 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/material3components/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.example.material3components", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/BadgeM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.size 4 | import androidx.compose.material.icons.Icons 5 | import androidx.compose.material.icons.filled.Favorite 6 | import androidx.compose.material3.Badge 7 | import androidx.compose.material3.BadgedBox 8 | import androidx.compose.material3.ExperimentalMaterial3Api 9 | import androidx.compose.material3.Icon 10 | import androidx.compose.material3.Text 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.ui.Modifier 13 | import androidx.compose.ui.unit.dp 14 | 15 | @OptIn(ExperimentalMaterial3Api::class) 16 | @Composable 17 | fun BadgeM3() { 18 | BadgedBox( 19 | badge = { 20 | Badge { Text(text = "99+")} 21 | } 22 | ) { 23 | Icon( 24 | imageVector = Icons.Default.Favorite, 25 | contentDescription = "Favorite", 26 | modifier = Modifier.size(40.dp) 27 | ) 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/BottomAppBarM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.PaddingValues 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.foundation.layout.padding 6 | import androidx.compose.foundation.lazy.LazyColumn 7 | import androidx.compose.material.icons.Icons 8 | import androidx.compose.material.icons.filled.Add 9 | import androidx.compose.material.icons.filled.Check 10 | import androidx.compose.material.icons.filled.Edit 11 | import androidx.compose.material.icons.filled.Face 12 | import androidx.compose.material.icons.filled.Search 13 | import androidx.compose.material.icons.filled.Share 14 | import androidx.compose.material3.BottomAppBar 15 | import androidx.compose.material3.BottomAppBarDefaults 16 | import androidx.compose.material3.FloatingActionButton 17 | import androidx.compose.material3.FloatingActionButtonDefaults 18 | import androidx.compose.material3.Icon 19 | import androidx.compose.material3.IconButton 20 | import androidx.compose.material3.ListItem 21 | import androidx.compose.material3.Scaffold 22 | import androidx.compose.material3.Text 23 | import androidx.compose.runtime.Composable 24 | import androidx.compose.ui.Modifier 25 | import androidx.compose.ui.unit.dp 26 | 27 | @Composable 28 | fun BottomAppBarWithScaffoldM3() { 29 | Scaffold( 30 | bottomBar = { BottomAppBarM3() } 31 | ) { padding -> 32 | LazyColumn( 33 | modifier = Modifier 34 | .fillMaxSize() 35 | .padding(padding), 36 | contentPadding = PaddingValues(16.dp) 37 | ) { 38 | items(50) { 39 | ListItem( 40 | headlineContent = { Text(text = "Item $it")}, 41 | leadingContent = { 42 | Icon(imageVector = Icons.Default.Face, contentDescription = null) 43 | } 44 | ) 45 | } 46 | } 47 | } 48 | } 49 | 50 | @Composable 51 | fun BottomAppBarM3() { 52 | BottomAppBar( 53 | actions = { 54 | IconButton(onClick = { /* do something */ }) { 55 | Icon(Icons.Filled.Check, contentDescription = null) 56 | } 57 | IconButton(onClick = { /* do something */ }) { 58 | Icon(Icons.Filled.Edit, contentDescription = null) 59 | } 60 | IconButton(onClick = { /* do something */ }) { 61 | Icon(Icons.Filled.Search, contentDescription = null) 62 | } 63 | IconButton(onClick = { /* do something */ }) { 64 | Icon(Icons.Filled.Share, contentDescription = null) 65 | } 66 | }, 67 | floatingActionButton = { 68 | FloatingActionButton( 69 | onClick = { /* do something */ }, 70 | elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation(), 71 | containerColor = BottomAppBarDefaults.bottomAppBarFabColor 72 | ) { 73 | Icon(Icons.Filled.Add, contentDescription = null) 74 | } 75 | } 76 | ) 77 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/BottomSheetM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Box 4 | import androidx.compose.foundation.layout.Column 5 | import androidx.compose.foundation.layout.PaddingValues 6 | import androidx.compose.foundation.layout.Spacer 7 | import androidx.compose.foundation.layout.fillMaxSize 8 | import androidx.compose.foundation.layout.fillMaxWidth 9 | import androidx.compose.foundation.layout.height 10 | import androidx.compose.foundation.layout.padding 11 | import androidx.compose.foundation.lazy.LazyColumn 12 | import androidx.compose.foundation.lazy.items 13 | import androidx.compose.material.icons.Icons 14 | import androidx.compose.material.icons.filled.Favorite 15 | import androidx.compose.material3.BottomSheetDefaults 16 | import androidx.compose.material3.BottomSheetScaffold 17 | import androidx.compose.material3.Button 18 | import androidx.compose.material3.Divider 19 | import androidx.compose.material3.ExperimentalMaterial3Api 20 | import androidx.compose.material3.Icon 21 | import androidx.compose.material3.ListItem 22 | import androidx.compose.material3.MaterialTheme 23 | import androidx.compose.material3.ModalBottomSheet 24 | import androidx.compose.material3.Text 25 | import androidx.compose.material3.rememberBottomSheetScaffoldState 26 | import androidx.compose.material3.rememberModalBottomSheetState 27 | import androidx.compose.runtime.Composable 28 | import androidx.compose.runtime.mutableStateOf 29 | import androidx.compose.runtime.remember 30 | import androidx.compose.runtime.getValue 31 | import androidx.compose.runtime.rememberCoroutineScope 32 | import androidx.compose.runtime.setValue 33 | import androidx.compose.ui.Alignment 34 | import androidx.compose.ui.Modifier 35 | import androidx.compose.ui.unit.dp 36 | import kotlinx.coroutines.launch 37 | 38 | @OptIn(ExperimentalMaterial3Api::class) 39 | @Composable 40 | fun ModalBottomSheetM3() { 41 | 42 | var openBottomSheet by remember { mutableStateOf(false) } 43 | val scope = rememberCoroutineScope() 44 | val bottomSheetState = rememberModalBottomSheetState( 45 | skipPartiallyExpanded = true 46 | ) 47 | 48 | Button(onClick = { openBottomSheet = true }) { 49 | Text(text = "Show Bottom Sheet") 50 | } 51 | 52 | if (openBottomSheet) { 53 | ModalBottomSheet( 54 | sheetState = bottomSheetState, 55 | onDismissRequest = { openBottomSheet = false }, 56 | dragHandle = { 57 | Column( 58 | modifier = Modifier.fillMaxWidth(), 59 | horizontalAlignment = Alignment.CenterHorizontally 60 | ) { 61 | BottomSheetDefaults.DragHandle() 62 | Text(text = "Comments", style = MaterialTheme.typography.titleLarge) 63 | Spacer(modifier = Modifier.height(10.dp)) 64 | Divider() 65 | } 66 | } 67 | ) { 68 | BottomSheetContent( 69 | onHideButtonClick = { 70 | scope.launch { bottomSheetState.hide() }.invokeOnCompletion { 71 | if (!bottomSheetState.isVisible) openBottomSheet = false 72 | } 73 | } 74 | ) 75 | } 76 | } 77 | } 78 | 79 | @OptIn(ExperimentalMaterial3Api::class) 80 | @Composable 81 | fun StandardBottomSheetM3() { 82 | 83 | val scope = rememberCoroutineScope() 84 | val scaffoldState = rememberBottomSheetScaffoldState() 85 | 86 | BottomSheetScaffold( 87 | scaffoldState = scaffoldState, 88 | sheetPeekHeight = 128.dp, 89 | sheetContent = { 90 | Box( 91 | modifier = Modifier 92 | .fillMaxWidth() 93 | .height(128.dp), 94 | contentAlignment = Alignment.Center 95 | ) { 96 | Text(text = "Swipe up to expand sheet") 97 | } 98 | Column( 99 | modifier = Modifier 100 | .fillMaxWidth() 101 | .padding(64.dp), 102 | horizontalAlignment = Alignment.CenterHorizontally 103 | ) { 104 | Text(text = "Sheet Content") 105 | Spacer(modifier = Modifier.height(20.dp)) 106 | Button( 107 | onClick = { scope.launch { scaffoldState.bottomSheetState.partialExpand() } } 108 | ) { 109 | Text(text = "Click to collapse sheet") 110 | } 111 | } 112 | } 113 | ) { innerPadding -> 114 | Box( 115 | modifier = Modifier 116 | .fillMaxSize() 117 | .padding(innerPadding), 118 | contentAlignment = Alignment.Center 119 | ) { 120 | Text(text = "Scaffold Content") 121 | } 122 | } 123 | } 124 | 125 | @Composable 126 | fun BottomSheetContent( 127 | onHideButtonClick: () -> Unit 128 | ) { 129 | LazyColumn( 130 | contentPadding = PaddingValues(16.dp) 131 | ) { 132 | items(5) { 133 | ListItem( 134 | headlineContent = { Text(text = "Item $it") }, 135 | leadingContent = { 136 | Icon(imageVector = Icons.Default.Favorite, contentDescription = null) 137 | } 138 | ) 139 | } 140 | item { 141 | Button( 142 | modifier = Modifier.fillMaxWidth(), 143 | onClick = onHideButtonClick 144 | ) { 145 | Text(text = "Cancel") 146 | } 147 | } 148 | } 149 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/CheckboxM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Arrangement 4 | import androidx.compose.foundation.layout.Column 5 | import androidx.compose.foundation.layout.Row 6 | import androidx.compose.foundation.layout.fillMaxSize 7 | import androidx.compose.foundation.layout.fillMaxWidth 8 | import androidx.compose.foundation.layout.height 9 | import androidx.compose.foundation.layout.padding 10 | import androidx.compose.foundation.selection.toggleable 11 | import androidx.compose.material3.Checkbox 12 | import androidx.compose.material3.Text 13 | import androidx.compose.runtime.Composable 14 | import androidx.compose.runtime.mutableStateMapOf 15 | import androidx.compose.runtime.remember 16 | import androidx.compose.ui.Alignment 17 | import androidx.compose.ui.Modifier 18 | import androidx.compose.ui.unit.dp 19 | 20 | @Composable 21 | fun CheckboxM3() { 22 | val items = listOf("Pickles", "Tomato", "Lettuce", "Cheese") 23 | val checkboxStates = remember { mutableStateMapOf().withDefault { false } } 24 | 25 | Column( 26 | modifier = Modifier.fillMaxSize(), 27 | verticalArrangement = Arrangement.Center 28 | ) { 29 | items.forEach { item -> 30 | Row( 31 | modifier = Modifier 32 | .fillMaxWidth() 33 | .height(56.dp) 34 | .toggleable( 35 | value = checkboxStates.getValue(item), 36 | onValueChange = { checkboxStates[item] = it } 37 | ) 38 | .padding(horizontal = 16.dp), 39 | verticalAlignment = Alignment.CenterVertically 40 | ) { 41 | Checkbox( 42 | checked = checkboxStates.getValue(item), 43 | onCheckedChange = null 44 | ) 45 | Text( 46 | text = item, 47 | modifier = Modifier.padding(start = 16.dp) 48 | ) 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/ChipsM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.size 4 | import androidx.compose.material.icons.Icons 5 | import androidx.compose.material.icons.filled.Done 6 | import androidx.compose.material.icons.filled.Settings 7 | import androidx.compose.material3.AssistChip 8 | import androidx.compose.material3.AssistChipDefaults 9 | import androidx.compose.material3.ElevatedAssistChip 10 | import androidx.compose.material3.ElevatedFilterChip 11 | import androidx.compose.material3.ElevatedSuggestionChip 12 | import androidx.compose.material3.ExperimentalMaterial3Api 13 | import androidx.compose.material3.FilterChip 14 | import androidx.compose.material3.FilterChipDefaults 15 | import androidx.compose.material3.Icon 16 | import androidx.compose.material3.InputChip 17 | import androidx.compose.material3.SuggestionChip 18 | import androidx.compose.material3.SuggestionChipDefaults 19 | import androidx.compose.material3.Text 20 | import androidx.compose.runtime.Composable 21 | import androidx.compose.runtime.mutableStateOf 22 | import androidx.compose.runtime.remember 23 | import androidx.compose.runtime.getValue 24 | import androidx.compose.runtime.setValue 25 | import androidx.compose.ui.Modifier 26 | 27 | @OptIn(ExperimentalMaterial3Api::class) 28 | @Composable 29 | fun AssistChipM3() { 30 | AssistChip( 31 | onClick = { /* do something! */ }, 32 | label = { Text(text = "Assist Chip")}, 33 | leadingIcon = { 34 | Icon( 35 | imageVector = Icons.Filled.Settings, 36 | contentDescription = null, 37 | modifier = Modifier.size(AssistChipDefaults.IconSize) 38 | ) 39 | } 40 | ) 41 | } 42 | 43 | @OptIn(ExperimentalMaterial3Api::class) 44 | @Composable 45 | fun ElevatedAssistChipM3() { 46 | ElevatedAssistChip( 47 | onClick = { /* do something! */ }, 48 | label = { Text(text = "Assist Chip")}, 49 | leadingIcon = { 50 | Icon( 51 | imageVector = Icons.Filled.Settings, 52 | contentDescription = null, 53 | modifier = Modifier.size(AssistChipDefaults.IconSize) 54 | ) 55 | } 56 | ) 57 | } 58 | 59 | @OptIn(ExperimentalMaterial3Api::class) 60 | @Composable 61 | fun FilterChipM3() { 62 | 63 | var selected by remember { mutableStateOf(false) } 64 | 65 | FilterChip( 66 | selected = selected, 67 | onClick = { selected = !selected }, 68 | label = { Text(text = "Filter Chip")}, 69 | leadingIcon = if (selected) { 70 | { 71 | Icon( 72 | imageVector = Icons.Filled.Done, 73 | contentDescription = null, 74 | modifier = Modifier.size(FilterChipDefaults.IconSize) 75 | ) 76 | } 77 | } else null 78 | ) 79 | } 80 | 81 | @OptIn(ExperimentalMaterial3Api::class) 82 | @Composable 83 | fun ElevatedFilterChipM3() { 84 | 85 | var selected by remember { mutableStateOf(false) } 86 | 87 | ElevatedFilterChip( 88 | selected = selected, 89 | onClick = { selected = !selected }, 90 | label = { Text(text = "Filter Chip")}, 91 | leadingIcon = if (selected) { 92 | { 93 | Icon( 94 | imageVector = Icons.Filled.Done, 95 | contentDescription = null, 96 | modifier = Modifier.size(FilterChipDefaults.IconSize) 97 | ) 98 | } 99 | } else null 100 | ) 101 | } 102 | 103 | @OptIn(ExperimentalMaterial3Api::class) 104 | @Composable 105 | fun SuggestionChipM3() { 106 | SuggestionChip( 107 | onClick = { /* do something! */ }, 108 | label = { Text(text = "Suggestion Chip")}, 109 | icon = { 110 | Icon( 111 | imageVector = Icons.Filled.Settings, 112 | contentDescription = null, 113 | modifier = Modifier.size(SuggestionChipDefaults.IconSize) 114 | ) 115 | } 116 | ) 117 | } 118 | 119 | @OptIn(ExperimentalMaterial3Api::class) 120 | @Composable 121 | fun ElevatedSuggestionChipM3() { 122 | ElevatedSuggestionChip( 123 | onClick = { /* do something! */ }, 124 | label = { Text(text = "Suggestion Chip")}, 125 | icon = { 126 | Icon( 127 | imageVector = Icons.Filled.Settings, 128 | contentDescription = null, 129 | modifier = Modifier.size(SuggestionChipDefaults.IconSize) 130 | ) 131 | } 132 | ) 133 | } 134 | 135 | @OptIn(ExperimentalMaterial3Api::class) 136 | @Composable 137 | fun InputChipM3() { 138 | var selected by remember { mutableStateOf(false) } 139 | InputChip( 140 | selected = selected, 141 | onClick = { selected = !selected }, 142 | label = { Text(text = "Input Chip")}, 143 | avatar = { 144 | Icon( 145 | imageVector = Icons.Filled.Settings, 146 | contentDescription = null, 147 | modifier = Modifier.size(SuggestionChipDefaults.IconSize) 148 | ) 149 | } 150 | ) 151 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/DialogM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Arrangement 4 | import androidx.compose.foundation.layout.Column 5 | import androidx.compose.foundation.layout.padding 6 | import androidx.compose.material.icons.Icons 7 | import androidx.compose.material.icons.filled.Delete 8 | import androidx.compose.material3.AlertDialog 9 | import androidx.compose.material3.Button 10 | import androidx.compose.material3.Icon 11 | import androidx.compose.material3.IconButton 12 | import androidx.compose.material3.MaterialTheme 13 | import androidx.compose.material3.Surface 14 | import androidx.compose.material3.Text 15 | import androidx.compose.material3.TextButton 16 | import androidx.compose.runtime.Composable 17 | import androidx.compose.runtime.mutableStateOf 18 | import androidx.compose.runtime.remember 19 | import androidx.compose.runtime.getValue 20 | import androidx.compose.runtime.setValue 21 | import androidx.compose.ui.Alignment 22 | import androidx.compose.ui.Modifier 23 | import androidx.compose.ui.unit.dp 24 | import androidx.compose.ui.window.Dialog 25 | 26 | @Composable 27 | fun AlertDialogM3() { 28 | 29 | var openDialog by remember { mutableStateOf(false) } 30 | 31 | IconButton(onClick = { openDialog = true }) { 32 | Icon( 33 | imageVector = Icons.Default.Delete, 34 | contentDescription = "Delete Icon" 35 | ) 36 | } 37 | 38 | if (openDialog) { 39 | AlertDialog( 40 | onDismissRequest = { openDialog = false }, 41 | title = { 42 | Text(text = "Delete Selected Image?") 43 | }, 44 | text = { 45 | Text(text = "Are you sure, you want to permanently delete the selected image.") 46 | }, 47 | confirmButton = { 48 | TextButton(onClick = { 49 | /* viewModel.deleteImage */ 50 | openDialog = false 51 | }) { 52 | Text(text = "Yes") 53 | } 54 | }, 55 | dismissButton = { 56 | TextButton(onClick = { openDialog = false }) { 57 | Text(text = "No") 58 | } 59 | } 60 | ) 61 | } 62 | } 63 | 64 | @Composable 65 | fun DialogM3() { 66 | var openDialog by remember { mutableStateOf(false) } 67 | 68 | IconButton(onClick = { openDialog = true }) { 69 | Icon( 70 | imageVector = Icons.Default.Delete, 71 | contentDescription = "Delete Icon" 72 | ) 73 | } 74 | 75 | if (openDialog) { 76 | Dialog(onDismissRequest = { openDialog = false }) { 77 | Surface { 78 | Column( 79 | modifier = Modifier.padding(10.dp), 80 | horizontalAlignment = Alignment.CenterHorizontally, 81 | verticalArrangement = Arrangement.spacedBy(10.dp) 82 | ) { 83 | Text( 84 | text = "Congratulation", 85 | style = MaterialTheme.typography.headlineMedium 86 | ) 87 | Text( 88 | text = "You have cleared all the stages", 89 | style = MaterialTheme.typography.titleMedium 90 | ) 91 | Button(onClick = { openDialog = false }) { 92 | Text(text = "Play") 93 | } 94 | } 95 | } 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/FABM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.PaddingValues 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.foundation.layout.padding 6 | import androidx.compose.foundation.layout.size 7 | import androidx.compose.foundation.lazy.LazyColumn 8 | import androidx.compose.foundation.lazy.rememberLazyListState 9 | import androidx.compose.material.icons.Icons 10 | import androidx.compose.material.icons.filled.Add 11 | import androidx.compose.material.icons.filled.Face 12 | import androidx.compose.material3.ExtendedFloatingActionButton 13 | import androidx.compose.material3.FabPosition 14 | import androidx.compose.material3.FloatingActionButton 15 | import androidx.compose.material3.FloatingActionButtonDefaults 16 | import androidx.compose.material3.Icon 17 | import androidx.compose.material3.LargeFloatingActionButton 18 | import androidx.compose.material3.ListItem 19 | import androidx.compose.material3.Scaffold 20 | import androidx.compose.material3.SmallFloatingActionButton 21 | import androidx.compose.material3.Text 22 | import androidx.compose.runtime.Composable 23 | import androidx.compose.runtime.derivedStateOf 24 | import androidx.compose.runtime.remember 25 | import androidx.compose.runtime.getValue 26 | import androidx.compose.runtime.setValue 27 | import androidx.compose.ui.Modifier 28 | import androidx.compose.ui.unit.dp 29 | 30 | @Composable 31 | fun FABWithScaffold() { 32 | 33 | val listState = rememberLazyListState() 34 | val isExpanded by remember { derivedStateOf { listState.firstVisibleItemIndex == 0 } } 35 | 36 | Scaffold( 37 | floatingActionButton = { 38 | ExtendedFABM3(expanded = isExpanded) 39 | }, 40 | floatingActionButtonPosition = FabPosition.Center 41 | ) { padding -> 42 | LazyColumn( 43 | state = listState, 44 | modifier = Modifier 45 | .fillMaxSize() 46 | .padding(padding), 47 | contentPadding = PaddingValues(16.dp) 48 | ) { 49 | items(50) { 50 | ListItem( 51 | headlineContent = { Text(text = "Item $it") }, 52 | leadingContent = { 53 | Icon(imageVector = Icons.Default.Face, contentDescription = null) 54 | } 55 | ) 56 | } 57 | } 58 | } 59 | } 60 | 61 | @Composable 62 | fun FABM3() { 63 | FloatingActionButton(onClick = { /* do something*/ }) { 64 | Icon(imageVector = Icons.Filled.Add, contentDescription = null) 65 | } 66 | } 67 | 68 | @Composable 69 | fun SmallFABM3() { 70 | SmallFloatingActionButton(onClick = { /* do something*/ }) { 71 | Icon(imageVector = Icons.Filled.Add, contentDescription = null) 72 | } 73 | } 74 | 75 | @Composable 76 | fun LargeFABM3() { 77 | LargeFloatingActionButton(onClick = { /* do something*/ }) { 78 | Icon( 79 | imageVector = Icons.Filled.Add, 80 | contentDescription = null, 81 | modifier = Modifier.size(FloatingActionButtonDefaults.LargeIconSize) 82 | ) 83 | } 84 | } 85 | 86 | @Composable 87 | fun ExtendedFABM3( 88 | expanded: Boolean 89 | ) { 90 | ExtendedFloatingActionButton( 91 | onClick = { /* do something*/ }, 92 | icon = { Icon(imageVector = Icons.Filled.Add, contentDescription = null) }, 93 | text = { Text(text = "Compose")}, 94 | expanded = expanded 95 | ) 96 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/ListsM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.fillMaxSize 4 | import androidx.compose.foundation.lazy.LazyColumn 5 | import androidx.compose.foundation.lazy.items 6 | import androidx.compose.material.icons.Icons 7 | import androidx.compose.material.icons.filled.MoreVert 8 | import androidx.compose.material.icons.outlined.Build 9 | import androidx.compose.material.icons.outlined.Call 10 | import androidx.compose.material.icons.outlined.Email 11 | import androidx.compose.material.icons.outlined.Lock 12 | import androidx.compose.material.icons.outlined.ShoppingCart 13 | import androidx.compose.material3.Icon 14 | import androidx.compose.material3.ListItem 15 | import androidx.compose.material3.Text 16 | import androidx.compose.runtime.Composable 17 | import androidx.compose.ui.Modifier 18 | import androidx.compose.ui.graphics.vector.ImageVector 19 | 20 | @Composable 21 | fun ListsM3() { 22 | LazyColumn( 23 | modifier = Modifier.fillMaxSize() 24 | ) { 25 | items(items = tasks, key = {it.id }) {task -> 26 | ListItem( 27 | headlineContent = { Text(text = task.name)}, 28 | supportingContent = {Text(text = task.description)}, 29 | leadingContent = { 30 | Icon(imageVector = task.icon, contentDescription = task.name) 31 | }, 32 | trailingContent = { 33 | Icon(imageVector = Icons.Default.MoreVert, contentDescription = task.name) 34 | } 35 | ) 36 | } 37 | } 38 | } 39 | 40 | data class Task( 41 | val id: Int, 42 | val name: String, 43 | val icon: ImageVector, 44 | val description: String 45 | ) 46 | 47 | val tasks = listOf( 48 | Task(1, "Buy Groceries", Icons.Outlined.ShoppingCart, "Milk, Eggs, Bread"), 49 | Task(2, "Call Mom", Icons.Outlined.Call, "Discuss plans"), 50 | Task(3, "Finish Kotlin Project", Icons.Outlined.Build, "Implement Search"), 51 | Task(4, "Go for a Run", Icons.Outlined.Lock, "5km around the park"), 52 | Task(5, "Read a Book", Icons.Outlined.Email, " Complete a chapter of '1920'"), 53 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.foundation.layout.Box 7 | import androidx.compose.foundation.layout.fillMaxSize 8 | import androidx.compose.material3.MaterialTheme 9 | import androidx.compose.material3.Surface 10 | import androidx.compose.ui.Alignment 11 | import androidx.compose.ui.Modifier 12 | import com.example.material3components.ui.theme.Material3ComponentsTheme 13 | 14 | class MainActivity : ComponentActivity() { 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | super.onCreate(savedInstanceState) 17 | setContent { 18 | Material3ComponentsTheme { 19 | Surface( 20 | modifier = Modifier.fillMaxSize(), 21 | color = MaterialTheme.colorScheme.background 22 | ) { 23 | 24 | } 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/MenuM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Box 4 | import androidx.compose.foundation.layout.wrapContentSize 5 | import androidx.compose.material.icons.Icons 6 | import androidx.compose.material.icons.filled.Edit 7 | import androidx.compose.material.icons.filled.Email 8 | import androidx.compose.material.icons.filled.MoreVert 9 | import androidx.compose.material.icons.filled.Settings 10 | import androidx.compose.material3.Divider 11 | import androidx.compose.material3.DropdownMenu 12 | import androidx.compose.material3.DropdownMenuItem 13 | import androidx.compose.material3.Icon 14 | import androidx.compose.material3.IconButton 15 | import androidx.compose.material3.Text 16 | import androidx.compose.runtime.Composable 17 | import androidx.compose.runtime.mutableStateOf 18 | import androidx.compose.runtime.remember 19 | import androidx.compose.runtime.getValue 20 | import androidx.compose.runtime.setValue 21 | import androidx.compose.ui.Modifier 22 | 23 | @Composable 24 | fun MenusM3() { 25 | 26 | var expanded by remember { mutableStateOf(false) } 27 | 28 | Box( 29 | modifier = Modifier.wrapContentSize() 30 | ) { 31 | IconButton(onClick = { expanded = true }) { 32 | Icon(Icons.Default.MoreVert, contentDescription = null) 33 | } 34 | DropdownMenu( 35 | expanded = expanded, 36 | onDismissRequest = { expanded = false } 37 | ) { 38 | DropdownMenuItem( 39 | text = { Text(text = "Edit") }, 40 | onClick = { /* Handle edit */ }, 41 | leadingIcon = { 42 | Icon(Icons.Default.Edit, contentDescription = null) 43 | } 44 | ) 45 | DropdownMenuItem( 46 | text = { Text(text = "Settings") }, 47 | onClick = { /* Handle settings */ }, 48 | leadingIcon = { 49 | Icon(Icons.Default.Settings, contentDescription = null) 50 | } 51 | ) 52 | Divider() 53 | DropdownMenuItem( 54 | text = { Text(text = "Send Feedback") }, 55 | onClick = { /* Handle feedback */ }, 56 | leadingIcon = { 57 | Icon(Icons.Default.Email, contentDescription = null) 58 | }, 59 | trailingIcon = { Text(text = "F11")} 60 | ) 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/NavigationBarM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.PaddingValues 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.foundation.layout.padding 6 | import androidx.compose.foundation.lazy.LazyColumn 7 | import androidx.compose.foundation.lazy.items 8 | import androidx.compose.material.icons.Icons 9 | import androidx.compose.material.icons.filled.Add 10 | import androidx.compose.material.icons.filled.Face 11 | import androidx.compose.material.icons.filled.Home 12 | import androidx.compose.material.icons.filled.Settings 13 | import androidx.compose.material.icons.filled.ShoppingCart 14 | import androidx.compose.material.icons.outlined.Face 15 | import androidx.compose.material.icons.outlined.Home 16 | import androidx.compose.material.icons.outlined.Settings 17 | import androidx.compose.material.icons.outlined.ShoppingCart 18 | import androidx.compose.material3.FloatingActionButton 19 | import androidx.compose.material3.Icon 20 | import androidx.compose.material3.ListItem 21 | import androidx.compose.material3.NavigationBar 22 | import androidx.compose.material3.NavigationBarItem 23 | import androidx.compose.material3.Scaffold 24 | import androidx.compose.material3.Text 25 | import androidx.compose.runtime.Composable 26 | import androidx.compose.runtime.mutableStateOf 27 | import androidx.compose.runtime.remember 28 | import androidx.compose.runtime.setValue 29 | import androidx.compose.runtime.getValue 30 | import androidx.compose.ui.Modifier 31 | import androidx.compose.ui.graphics.vector.ImageVector 32 | import androidx.compose.ui.unit.dp 33 | 34 | @Composable 35 | fun NavigationBarWithScaffold() { 36 | Scaffold( 37 | bottomBar = { NavigationBarM3() }, 38 | floatingActionButton = { 39 | FloatingActionButton(onClick = { /*TODO*/ }) { 40 | Icon(imageVector = Icons.Default.Add, contentDescription = "Add") 41 | } 42 | } 43 | ) { padding -> 44 | LazyColumn( 45 | modifier = Modifier 46 | .fillMaxSize() 47 | .padding(padding), 48 | contentPadding = PaddingValues(16.dp) 49 | ) { 50 | items(50) { 51 | ListItem( 52 | headlineContent = { Text(text = "Item $it") }, 53 | leadingContent = { 54 | Icon(imageVector = Icons.Default.Face, contentDescription = null) 55 | } 56 | ) 57 | } 58 | } 59 | } 60 | } 61 | 62 | @Composable 63 | fun NavigationBarM3() { 64 | var selectedItem by remember { mutableStateOf(0) } 65 | val barItems = listOf( 66 | BarItem( 67 | title = "Home", 68 | selectedIcon = Icons.Filled.Home, 69 | unselectedIcon = Icons.Outlined.Home, 70 | route = "home" 71 | ), 72 | BarItem( 73 | title = "Contacts", 74 | selectedIcon = Icons.Filled.Face, 75 | unselectedIcon = Icons.Outlined.Face, 76 | route = "contacts" 77 | ), 78 | BarItem( 79 | title = "Settings", 80 | selectedIcon = Icons.Filled.Settings, 81 | unselectedIcon = Icons.Outlined.Settings, 82 | route = "setting" 83 | ), 84 | BarItem( 85 | title = "Shop", 86 | selectedIcon = Icons.Filled.ShoppingCart, 87 | unselectedIcon = Icons.Outlined.ShoppingCart, 88 | route = "shop" 89 | ) 90 | ) 91 | 92 | NavigationBar { 93 | barItems.forEachIndexed { index, barItem -> 94 | val selected = selectedItem == index 95 | NavigationBarItem( 96 | selected = selected, 97 | onClick = { 98 | selectedItem = index 99 | /* navigate to selected route */ 100 | }, 101 | icon = { 102 | Icon( 103 | imageVector = if (selected) barItem.selectedIcon else barItem.unselectedIcon, 104 | contentDescription = barItem.title 105 | ) 106 | }, 107 | label = { Text(text = barItem.title) }, 108 | alwaysShowLabel = selected 109 | ) 110 | } 111 | } 112 | } 113 | 114 | data class BarItem( 115 | val title: String, 116 | val selectedIcon: ImageVector, 117 | val unselectedIcon: ImageVector, 118 | val route: String 119 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/NavigationDrawerM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Arrangement 4 | import androidx.compose.foundation.layout.Box 5 | import androidx.compose.foundation.layout.Column 6 | import androidx.compose.foundation.layout.PaddingValues 7 | import androidx.compose.foundation.layout.Spacer 8 | import androidx.compose.foundation.layout.fillMaxSize 9 | import androidx.compose.foundation.layout.fillMaxWidth 10 | import androidx.compose.foundation.layout.height 11 | import androidx.compose.foundation.layout.padding 12 | import androidx.compose.foundation.lazy.LazyColumn 13 | import androidx.compose.material.icons.Icons 14 | import androidx.compose.material.icons.filled.Email 15 | import androidx.compose.material.icons.filled.Face 16 | import androidx.compose.material.icons.filled.Favorite 17 | import androidx.compose.material.icons.filled.Menu 18 | import androidx.compose.material.icons.filled.Settings 19 | import androidx.compose.material3.Button 20 | import androidx.compose.material3.DrawerValue 21 | import androidx.compose.material3.ExperimentalMaterial3Api 22 | import androidx.compose.material3.Icon 23 | import androidx.compose.material3.IconButton 24 | import androidx.compose.material3.ListItem 25 | import androidx.compose.material3.MaterialTheme 26 | import androidx.compose.material3.ModalDrawerSheet 27 | import androidx.compose.material3.ModalNavigationDrawer 28 | import androidx.compose.material3.NavigationDrawerItem 29 | import androidx.compose.material3.NavigationDrawerItemDefaults 30 | import androidx.compose.material3.Scaffold 31 | import androidx.compose.material3.Text 32 | import androidx.compose.material3.TopAppBar 33 | import androidx.compose.material3.rememberDrawerState 34 | import androidx.compose.runtime.Composable 35 | import androidx.compose.runtime.mutableStateOf 36 | import androidx.compose.runtime.remember 37 | import androidx.compose.runtime.getValue 38 | import androidx.compose.runtime.rememberCoroutineScope 39 | import androidx.compose.runtime.setValue 40 | import androidx.compose.ui.Alignment 41 | import androidx.compose.ui.Modifier 42 | import androidx.compose.ui.graphics.vector.ImageVector 43 | import androidx.compose.ui.unit.dp 44 | import kotlinx.coroutines.launch 45 | 46 | @Composable 47 | fun NavigationDrawerM3() { 48 | 49 | val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed) 50 | val scope = rememberCoroutineScope() 51 | val items = listOf( 52 | DrawerItem(icon = Icons.Default.Favorite, label = "Likes", secondaryLabel = "64"), 53 | DrawerItem(icon = Icons.Default.Face, label = "Messages", secondaryLabel = "12"), 54 | DrawerItem(icon = Icons.Default.Email, label = "Mail", secondaryLabel = "64"), 55 | DrawerItem(icon = Icons.Default.Settings, label = "Settings", secondaryLabel = ""), 56 | ) 57 | var selectedItem by remember { mutableStateOf(items[0]) } 58 | 59 | ModalNavigationDrawer( 60 | drawerState = drawerState, 61 | gesturesEnabled = drawerState.isOpen, 62 | drawerContent = { 63 | ModalDrawerSheet { 64 | Box( 65 | modifier = Modifier 66 | .fillMaxWidth() 67 | .padding(vertical = 64.dp), 68 | contentAlignment = Alignment.Center 69 | ) { 70 | Text(text = "Header", style = MaterialTheme.typography.headlineLarge) 71 | } 72 | items.forEach { item -> 73 | NavigationDrawerItem( 74 | label = { Text(text = item.label) }, 75 | selected = item == selectedItem, 76 | onClick = { 77 | scope.launch { drawerState.close() } 78 | selectedItem = item 79 | }, 80 | icon = { Icon(imageVector = item.icon, contentDescription = item.label)}, 81 | badge = { Text(text = item.secondaryLabel)}, 82 | modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding) 83 | ) 84 | } 85 | } 86 | }, 87 | content = { 88 | Content2( 89 | onMenuIconClick = { scope.launch { drawerState.open() } } 90 | ) 91 | } 92 | ) 93 | } 94 | 95 | data class DrawerItem( 96 | val icon: ImageVector, 97 | val label: String, 98 | val secondaryLabel: String 99 | ) 100 | 101 | @Composable 102 | fun Content( 103 | onClick: () -> Unit 104 | ) { 105 | Column( 106 | modifier = Modifier.fillMaxSize(), 107 | horizontalAlignment = Alignment.CenterHorizontally, 108 | verticalArrangement = Arrangement.Center 109 | ) { 110 | Text(text = ">>> Swipe >>>") 111 | Spacer(modifier = Modifier.height(20.dp)) 112 | Button(onClick = onClick) { 113 | Text(text = "Click to Open") 114 | } 115 | } 116 | } 117 | 118 | @OptIn(ExperimentalMaterial3Api::class) 119 | @Composable 120 | fun Content2( 121 | onMenuIconClick: () -> Unit 122 | ) { 123 | Scaffold( 124 | topBar = { 125 | TopAppBar( 126 | navigationIcon = { 127 | IconButton(onClick = onMenuIconClick) { 128 | Icon(imageVector = Icons.Default.Menu, contentDescription = "Open Drawer") 129 | } 130 | }, 131 | title = { Text(text = "Top Stories")} 132 | ) 133 | } 134 | ) { padding -> 135 | LazyColumn( 136 | modifier = Modifier 137 | .fillMaxSize() 138 | .padding(padding), 139 | contentPadding = PaddingValues(16.dp) 140 | ) { 141 | items(50) { 142 | ListItem( 143 | headlineContent = { Text(text = "Item $it")}, 144 | leadingContent = { 145 | Icon(Icons.Default.Face, contentDescription = null) 146 | } 147 | ) 148 | } 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/ProgressIndicatorsM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.animation.core.animateFloatAsState 4 | import androidx.compose.foundation.layout.Arrangement 5 | import androidx.compose.foundation.layout.Column 6 | import androidx.compose.foundation.layout.fillMaxSize 7 | import androidx.compose.material3.Button 8 | import androidx.compose.material3.CircularProgressIndicator 9 | import androidx.compose.material3.LinearProgressIndicator 10 | import androidx.compose.material3.ProgressIndicatorDefaults 11 | import androidx.compose.material3.Text 12 | import androidx.compose.runtime.Composable 13 | import androidx.compose.runtime.mutableStateOf 14 | import androidx.compose.runtime.remember 15 | import androidx.compose.runtime.getValue 16 | import androidx.compose.runtime.setValue 17 | import androidx.compose.ui.Alignment 18 | import androidx.compose.ui.Modifier 19 | import androidx.compose.ui.unit.dp 20 | 21 | @Composable 22 | fun CircularProgressIndicatorM3() { 23 | 24 | var isLoading by remember { mutableStateOf(false) } 25 | 26 | Column( 27 | modifier = Modifier.fillMaxSize(), 28 | horizontalAlignment = Alignment.CenterHorizontally, 29 | verticalArrangement = Arrangement.Center 30 | ) { 31 | if (isLoading) { 32 | CircularProgressIndicator() 33 | } 34 | Button(onClick = { isLoading = !isLoading }) { 35 | Text(text = "Click Here") 36 | } 37 | } 38 | } 39 | 40 | @Composable 41 | fun CircularProgressIndicator2M3() { 42 | 43 | var progress by remember { mutableStateOf(0.1f) } 44 | val animatedProgress by animateFloatAsState( 45 | targetValue = progress, 46 | animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec 47 | ) 48 | 49 | Column( 50 | modifier = Modifier.fillMaxSize(), 51 | horizontalAlignment = Alignment.CenterHorizontally, 52 | verticalArrangement = Arrangement.Center 53 | ) { 54 | CircularProgressIndicator(progress = animatedProgress) 55 | Button(onClick = { 56 | if (progress < 1f) progress += 0.1f 57 | }) { 58 | Text(text = "Click Here") 59 | } 60 | } 61 | } 62 | 63 | @Composable 64 | fun LinearProgressIndicatorM3() { 65 | 66 | var isLoading by remember { mutableStateOf(false) } 67 | 68 | Column( 69 | modifier = Modifier.fillMaxSize(), 70 | horizontalAlignment = Alignment.CenterHorizontally, 71 | verticalArrangement = Arrangement.Center 72 | ) { 73 | if (isLoading) { 74 | LinearProgressIndicator() 75 | } 76 | Button(onClick = { isLoading = !isLoading }) { 77 | Text(text = "Click Here") 78 | } 79 | } 80 | } 81 | 82 | @Composable 83 | fun LinearProgressIndicator2M3() { 84 | 85 | var progress by remember { mutableStateOf(0.1f) } 86 | val animatedProgress by animateFloatAsState( 87 | targetValue = progress, 88 | animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec 89 | ) 90 | 91 | Column( 92 | modifier = Modifier.fillMaxSize(), 93 | horizontalAlignment = Alignment.CenterHorizontally, 94 | verticalArrangement = Arrangement.Center 95 | ) { 96 | LinearProgressIndicator(progress = animatedProgress) 97 | Button(onClick = { 98 | if (progress < 1f) progress += 0.1f 99 | }) { 100 | Text(text = "Click Here") 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/RadioButtonM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Arrangement 4 | import androidx.compose.foundation.layout.Column 5 | import androidx.compose.foundation.layout.Row 6 | import androidx.compose.foundation.layout.fillMaxSize 7 | import androidx.compose.foundation.layout.fillMaxWidth 8 | import androidx.compose.foundation.layout.height 9 | import androidx.compose.foundation.layout.padding 10 | import androidx.compose.foundation.selection.selectable 11 | import androidx.compose.material3.RadioButton 12 | import androidx.compose.material3.Text 13 | import androidx.compose.runtime.Composable 14 | import androidx.compose.runtime.getValue 15 | import androidx.compose.runtime.mutableStateOf 16 | import androidx.compose.runtime.remember 17 | import androidx.compose.runtime.setValue 18 | import androidx.compose.ui.Alignment 19 | import androidx.compose.ui.Modifier 20 | import androidx.compose.ui.unit.dp 21 | 22 | @Composable 23 | fun RadioButtonM3() { 24 | val options = listOf("English", "Hindi", "Urdu") 25 | var selectedOption by remember { mutableStateOf(options[0]) } 26 | 27 | Column( 28 | modifier = Modifier.fillMaxSize(), 29 | verticalArrangement = Arrangement.Center 30 | ) { 31 | options.forEach { option -> 32 | Row( 33 | modifier = Modifier 34 | .fillMaxWidth() 35 | .height(56.dp) 36 | .selectable( 37 | selected = selectedOption == option, 38 | onClick = { selectedOption = option } 39 | ) 40 | .padding(horizontal = 16.dp), 41 | verticalAlignment = Alignment.CenterVertically 42 | ) { 43 | RadioButton( 44 | selected = selectedOption == option, 45 | onClick = null 46 | ) 47 | Text( 48 | text = option, 49 | modifier = Modifier.padding(start = 16.dp) 50 | ) 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/SearchBarM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.clickable 4 | import androidx.compose.foundation.layout.Row 5 | import androidx.compose.material.icons.Icons 6 | import androidx.compose.material.icons.filled.Close 7 | import androidx.compose.material.icons.filled.Search 8 | import androidx.compose.material3.DockedSearchBar 9 | import androidx.compose.material3.ExperimentalMaterial3Api 10 | import androidx.compose.material3.Icon 11 | import androidx.compose.material3.IconButton 12 | import androidx.compose.material3.ListItem 13 | import androidx.compose.material3.SearchBar 14 | import androidx.compose.material3.Text 15 | import androidx.compose.runtime.Composable 16 | import androidx.compose.runtime.mutableStateOf 17 | import androidx.compose.runtime.remember 18 | import androidx.compose.runtime.getValue 19 | import androidx.compose.runtime.setValue 20 | import androidx.compose.ui.Modifier 21 | import androidx.compose.ui.res.painterResource 22 | 23 | @OptIn(ExperimentalMaterial3Api::class) 24 | @Composable 25 | fun SearchBarM3() { 26 | 27 | var query by remember { mutableStateOf("") } 28 | var active by remember { mutableStateOf(false) } 29 | 30 | val searchHistory = listOf("Android", "Kotlin", "Compose", "Material Design", "GPT-4") 31 | 32 | SearchBar( 33 | query = query, 34 | onQueryChange = { query = it }, 35 | onSearch = { newQuery -> 36 | println("Performing search on query: $newQuery") 37 | }, 38 | active = active, 39 | onActiveChange = { active = it }, 40 | placeholder = { 41 | Text(text = "Search") 42 | }, 43 | leadingIcon = { 44 | Icon(imageVector = Icons.Filled.Search, contentDescription = "Search") 45 | }, 46 | trailingIcon = { 47 | Row { 48 | IconButton(onClick = { /* open mic dialog */ }) { 49 | Icon(painter = painterResource(R.drawable.ic_mic), contentDescription = "Mic") 50 | } 51 | if (active) { 52 | IconButton( 53 | onClick = { if (query.isNotEmpty()) query = "" else active = false } 54 | ) { 55 | Icon(imageVector = Icons.Filled.Close, contentDescription = "Close") 56 | } 57 | } 58 | } 59 | } 60 | ) { 61 | searchHistory.takeLast(3).forEach { item -> 62 | ListItem( 63 | modifier = Modifier.clickable { query = item }, 64 | headlineContent = { Text(text = item) }, 65 | leadingContent = { 66 | Icon( 67 | painter = painterResource(R.drawable.ic_history), 68 | contentDescription = null 69 | ) 70 | } 71 | ) 72 | } 73 | } 74 | } 75 | 76 | @OptIn(ExperimentalMaterial3Api::class) 77 | @Composable 78 | fun DockedSearchBarM3() { 79 | var query by remember { mutableStateOf("") } 80 | var active by remember { mutableStateOf(false) } 81 | 82 | val searchHistory = listOf("Android", "Kotlin", "Compose", "Material Design", "GPT-4") 83 | 84 | DockedSearchBar( 85 | query = query, 86 | onQueryChange = { query = it }, 87 | onSearch = { newQuery -> 88 | println("Performing search on query: $newQuery") 89 | }, 90 | active = active, 91 | onActiveChange = { active = it }, 92 | placeholder = { 93 | Text(text = "Search") 94 | }, 95 | leadingIcon = { 96 | Icon(imageVector = Icons.Filled.Search, contentDescription = "Search") 97 | }, 98 | trailingIcon = { 99 | Row { 100 | IconButton(onClick = { /* open mic dialog */ }) { 101 | Icon(painter = painterResource(R.drawable.ic_mic), contentDescription = "Mic") 102 | } 103 | if (active) { 104 | IconButton( 105 | onClick = { if (query.isNotEmpty()) query = "" else active = false } 106 | ) { 107 | Icon(imageVector = Icons.Filled.Close, contentDescription = "Close") 108 | } 109 | } 110 | } 111 | } 112 | ) { 113 | searchHistory.takeLast(3).forEach { item -> 114 | ListItem( 115 | modifier = Modifier.clickable { query = item }, 116 | headlineContent = { Text(text = item) }, 117 | leadingContent = { 118 | Icon( 119 | painter = painterResource(R.drawable.ic_history), 120 | contentDescription = null 121 | ) 122 | } 123 | ) 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/SliderM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Column 4 | import androidx.compose.foundation.layout.padding 5 | import androidx.compose.foundation.layout.size 6 | import androidx.compose.material.icons.Icons 7 | import androidx.compose.material.icons.filled.Favorite 8 | import androidx.compose.material3.ButtonDefaults 9 | import androidx.compose.material3.ExperimentalMaterial3Api 10 | import androidx.compose.material3.Icon 11 | import androidx.compose.material3.RangeSlider 12 | import androidx.compose.material3.Slider 13 | import androidx.compose.material3.Text 14 | import androidx.compose.runtime.Composable 15 | import androidx.compose.runtime.mutableStateOf 16 | import androidx.compose.runtime.remember 17 | import androidx.compose.runtime.getValue 18 | import androidx.compose.runtime.setValue 19 | import androidx.compose.ui.Alignment 20 | import androidx.compose.ui.Modifier 21 | import androidx.compose.ui.graphics.Color 22 | import androidx.compose.ui.unit.dp 23 | 24 | @OptIn(ExperimentalMaterial3Api::class) 25 | @Composable 26 | fun SliderM3() { 27 | 28 | var sliderPosition by remember { mutableStateOf(0f) } 29 | 30 | Column( 31 | modifier = Modifier.padding(horizontal = 10.dp), 32 | horizontalAlignment = Alignment.CenterHorizontally 33 | ) { 34 | Text(text = sliderPosition.toString()) 35 | Slider( 36 | value = sliderPosition, 37 | onValueChange = { sliderPosition = it }, 38 | valueRange = 0f..5f, 39 | steps = 4, 40 | onValueChangeFinished = { 41 | //viewModel.updateSelectedSliderValue(sliderPosition) 42 | }, 43 | thumb = { 44 | Icon( 45 | imageVector = Icons.Filled.Favorite, 46 | contentDescription = null, 47 | modifier = Modifier.size(ButtonDefaults.IconSize), 48 | tint = Color.Red 49 | ) 50 | } 51 | ) 52 | } 53 | } 54 | 55 | @OptIn(ExperimentalMaterial3Api::class) 56 | @Composable 57 | fun RangeSliderM3() { 58 | var sliderPosition by remember { mutableStateOf(0f..100f) } 59 | 60 | Column( 61 | modifier = Modifier.padding(horizontal = 10.dp), 62 | horizontalAlignment = Alignment.CenterHorizontally 63 | ) { 64 | Text(text = sliderPosition.toString()) 65 | RangeSlider( 66 | value = sliderPosition, 67 | onValueChange = {sliderPosition = it}, 68 | valueRange = 0f..100f 69 | ) 70 | } 71 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/SnackbarM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Box 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.foundation.layout.padding 6 | import androidx.compose.material3.Button 7 | import androidx.compose.material3.Scaffold 8 | import androidx.compose.material3.SnackbarDuration 9 | import androidx.compose.material3.SnackbarHost 10 | import androidx.compose.material3.SnackbarHostState 11 | import androidx.compose.material3.SnackbarResult 12 | import androidx.compose.material3.Text 13 | import androidx.compose.runtime.Composable 14 | import androidx.compose.runtime.remember 15 | import androidx.compose.runtime.rememberCoroutineScope 16 | import androidx.compose.ui.Alignment 17 | import androidx.compose.ui.Modifier 18 | import kotlinx.coroutines.launch 19 | 20 | @Composable 21 | fun SnackbarM3() { 22 | val snackbarHostState = remember { SnackbarHostState() } 23 | val scope = rememberCoroutineScope() 24 | Scaffold( 25 | snackbarHost = { SnackbarHost(hostState = snackbarHostState) } 26 | ) { padding -> 27 | Box( 28 | modifier = Modifier 29 | .fillMaxSize() 30 | .padding(padding), 31 | contentAlignment = Alignment.Center 32 | ) { 33 | Button( 34 | onClick = { 35 | scope.launch { 36 | val result = snackbarHostState.showSnackbar( 37 | message = "Couldn't send photo", 38 | actionLabel = "Retry", 39 | withDismissAction = true, 40 | duration = SnackbarDuration.Long 41 | ) 42 | when (result) { 43 | SnackbarResult.Dismissed -> { 44 | 45 | } 46 | 47 | SnackbarResult.ActionPerformed -> { 48 | /* viewModel.sendPhoto*/ 49 | } 50 | } 51 | } 52 | } 53 | ) { 54 | Text(text = "Show Snackbar") 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/SwitchM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.size 4 | import androidx.compose.material.icons.Icons 5 | import androidx.compose.material.icons.filled.Check 6 | import androidx.compose.material.icons.filled.Close 7 | import androidx.compose.material3.Icon 8 | import androidx.compose.material3.Switch 9 | import androidx.compose.material3.SwitchDefaults 10 | import androidx.compose.runtime.Composable 11 | import androidx.compose.runtime.mutableStateOf 12 | import androidx.compose.runtime.remember 13 | import androidx.compose.runtime.getValue 14 | import androidx.compose.runtime.setValue 15 | import androidx.compose.ui.Modifier 16 | 17 | @Composable 18 | fun SwitchM3() { 19 | 20 | var isChecked by remember { mutableStateOf(false) } 21 | 22 | val icons = if (isChecked) Icons.Filled.Check else Icons.Filled.Close 23 | 24 | val icon: (@Composable () -> Unit)? = if (isChecked) { 25 | { 26 | Icon( 27 | imageVector = Icons.Filled.Check, 28 | contentDescription = null, 29 | modifier = Modifier.size(SwitchDefaults.IconSize) 30 | ) 31 | } 32 | } else null 33 | 34 | Switch( 35 | checked = isChecked, 36 | onCheckedChange = { isChecked = it }, 37 | thumbContent = icon 38 | ) 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/TextFieldsM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.Arrangement 4 | import androidx.compose.foundation.layout.Column 5 | import androidx.compose.foundation.layout.Spacer 6 | import androidx.compose.foundation.layout.fillMaxSize 7 | import androidx.compose.foundation.layout.fillMaxWidth 8 | import androidx.compose.foundation.layout.height 9 | import androidx.compose.foundation.layout.padding 10 | import androidx.compose.foundation.layout.size 11 | import androidx.compose.foundation.text.KeyboardActions 12 | import androidx.compose.foundation.text.KeyboardOptions 13 | import androidx.compose.material.icons.Icons 14 | import androidx.compose.material.icons.filled.Close 15 | import androidx.compose.material.icons.filled.Email 16 | import androidx.compose.material3.ExperimentalMaterial3Api 17 | import androidx.compose.material3.Icon 18 | import androidx.compose.material3.IconButton 19 | import androidx.compose.material3.OutlinedTextField 20 | import androidx.compose.material3.Text 21 | import androidx.compose.material3.TextField 22 | import androidx.compose.runtime.Composable 23 | import androidx.compose.runtime.getValue 24 | import androidx.compose.runtime.setValue 25 | import androidx.compose.runtime.mutableStateOf 26 | import androidx.compose.runtime.saveable.rememberSaveable 27 | import androidx.compose.ui.Alignment 28 | import androidx.compose.ui.ExperimentalComposeUiApi 29 | import androidx.compose.ui.Modifier 30 | import androidx.compose.ui.platform.LocalSoftwareKeyboardController 31 | import androidx.compose.ui.res.painterResource 32 | import androidx.compose.ui.text.input.ImeAction 33 | import androidx.compose.ui.text.input.KeyboardType 34 | import androidx.compose.ui.text.input.PasswordVisualTransformation 35 | import androidx.compose.ui.text.input.VisualTransformation 36 | import androidx.compose.ui.unit.dp 37 | 38 | @OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class) 39 | @Composable 40 | fun TextFieldsM3() { 41 | 42 | var email by rememberSaveable { mutableStateOf("") } 43 | var password by rememberSaveable { mutableStateOf("") } 44 | var isPasswordHidden by rememberSaveable { mutableStateOf(true) } 45 | val keyboardController = LocalSoftwareKeyboardController.current 46 | 47 | Column( 48 | modifier = Modifier.fillMaxSize(), 49 | horizontalAlignment = Alignment.CenterHorizontally, 50 | verticalArrangement = Arrangement.Center 51 | ) { 52 | OutlinedTextField( 53 | modifier = Modifier 54 | .fillMaxWidth() 55 | .padding(horizontal = 10.dp), 56 | value = email, 57 | onValueChange = { email = it }, 58 | label = { Text(text = "Email") }, 59 | placeholder = { Text(text = "Enter your email") }, 60 | leadingIcon = { 61 | Icon(imageVector = Icons.Default.Email, contentDescription = null) 62 | }, 63 | trailingIcon = if (email.isNotEmpty()) { 64 | { 65 | IconButton(onClick = { email = "" }) { 66 | Icon(imageVector = Icons.Default.Close, contentDescription = null) 67 | } 68 | } 69 | } else null, 70 | supportingText = { Text(text = "Please use the company email address.") }, 71 | isError = email.contains('.'), 72 | keyboardOptions = KeyboardOptions( 73 | keyboardType = KeyboardType.Email, 74 | imeAction = ImeAction.Done 75 | ), 76 | keyboardActions = KeyboardActions( 77 | onDone = { keyboardController?.hide() } 78 | ), 79 | singleLine = true 80 | ) 81 | Spacer(modifier = Modifier.height(10.dp)) 82 | TextField( 83 | modifier = Modifier 84 | .fillMaxWidth() 85 | .padding(horizontal = 10.dp), 86 | value = password, 87 | onValueChange = { password = it }, 88 | label = { Text(text = "Password") }, 89 | keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), 90 | visualTransformation = if (isPasswordHidden) { 91 | PasswordVisualTransformation() 92 | } else VisualTransformation.None, 93 | trailingIcon = { 94 | val visibilityIcon = if (isPasswordHidden) { 95 | painterResource(R.drawable.ic_visibility) 96 | } else painterResource(R.drawable.ic_visibility_off) 97 | IconButton(onClick = { isPasswordHidden = !isPasswordHidden }) { 98 | Icon( 99 | painter = visibilityIcon, 100 | contentDescription = null, 101 | modifier = Modifier.size(30.dp) 102 | ) 103 | } 104 | } 105 | ) 106 | } 107 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/TopAppBarM3.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components 2 | 3 | import androidx.compose.foundation.layout.PaddingValues 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.foundation.layout.padding 6 | import androidx.compose.foundation.lazy.LazyColumn 7 | import androidx.compose.foundation.lazy.items 8 | import androidx.compose.material.icons.Icons 9 | import androidx.compose.material.icons.filled.Face 10 | import androidx.compose.material.icons.filled.Favorite 11 | import androidx.compose.material.icons.filled.Menu 12 | import androidx.compose.material.icons.filled.MoreVert 13 | import androidx.compose.material.icons.filled.Settings 14 | import androidx.compose.material3.CenterAlignedTopAppBar 15 | import androidx.compose.material3.ExperimentalMaterial3Api 16 | import androidx.compose.material3.Icon 17 | import androidx.compose.material3.IconButton 18 | import androidx.compose.material3.LargeTopAppBar 19 | import androidx.compose.material3.ListItem 20 | import androidx.compose.material3.MediumTopAppBar 21 | import androidx.compose.material3.Scaffold 22 | import androidx.compose.material3.Text 23 | import androidx.compose.material3.TopAppBar 24 | import androidx.compose.material3.TopAppBarDefaults 25 | import androidx.compose.material3.TopAppBarScrollBehavior 26 | import androidx.compose.runtime.Composable 27 | import androidx.compose.ui.Modifier 28 | import androidx.compose.ui.input.nestedscroll.nestedScroll 29 | import androidx.compose.ui.text.style.TextOverflow 30 | import androidx.compose.ui.unit.dp 31 | 32 | @OptIn(ExperimentalMaterial3Api::class) 33 | @Composable 34 | fun TopAppBarWithScaffold() { 35 | val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() 36 | Scaffold( 37 | modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), 38 | topBar = { LargeTopAppBarM3(scrollBehavior = scrollBehavior) } 39 | ) { padding -> 40 | LazyColumn( 41 | modifier = Modifier 42 | .fillMaxSize() 43 | .padding(padding), 44 | contentPadding = PaddingValues(16.dp) 45 | ) { 46 | items(50) { 47 | ListItem( 48 | headlineContent = { Text(text = "Item $it") }, 49 | leadingContent = { 50 | Icon( 51 | imageVector = Icons.Default.Face, 52 | contentDescription = null 53 | ) 54 | } 55 | ) 56 | } 57 | } 58 | } 59 | } 60 | 61 | @OptIn(ExperimentalMaterial3Api::class) 62 | @Composable 63 | fun TopAppBarM3( 64 | scrollBehavior: TopAppBarScrollBehavior 65 | ) { 66 | TopAppBar( 67 | scrollBehavior = scrollBehavior, 68 | title = { Text(text = "Top Stories") }, 69 | navigationIcon = { 70 | IconButton(onClick = { /* do something*/ }) { 71 | Icon(imageVector = Icons.Filled.Menu, contentDescription = "Open Menu") 72 | } 73 | }, 74 | actions = { 75 | IconButton(onClick = { /* do something*/ }) { 76 | Icon(imageVector = Icons.Filled.Favorite, contentDescription = "Open Likes") 77 | } 78 | IconButton(onClick = { /* do something*/ }) { 79 | Icon(imageVector = Icons.Filled.Settings, contentDescription = "Open Settings") 80 | } 81 | } 82 | ) 83 | } 84 | 85 | @OptIn(ExperimentalMaterial3Api::class) 86 | @Composable 87 | fun CenterTopAppBarM3( 88 | scrollBehavior: TopAppBarScrollBehavior 89 | ) { 90 | CenterAlignedTopAppBar( 91 | scrollBehavior = scrollBehavior, 92 | title = { Text(text = "Top Stories") }, 93 | navigationIcon = { 94 | IconButton(onClick = { /* do something*/ }) { 95 | Icon(imageVector = Icons.Filled.Menu, contentDescription = "Open Menu") 96 | } 97 | }, 98 | actions = { 99 | IconButton(onClick = { /* do something*/ }) { 100 | Icon(imageVector = Icons.Filled.Favorite, contentDescription = "Open Likes") 101 | } 102 | IconButton(onClick = { /* do something*/ }) { 103 | Icon(imageVector = Icons.Filled.Settings, contentDescription = "Open Settings") 104 | } 105 | } 106 | ) 107 | } 108 | 109 | @OptIn(ExperimentalMaterial3Api::class) 110 | @Composable 111 | fun MediumTopAppBarM3( 112 | scrollBehavior: TopAppBarScrollBehavior 113 | ) { 114 | MediumTopAppBar( 115 | scrollBehavior = scrollBehavior, 116 | title = { Text(text = "Top Stories") }, 117 | navigationIcon = { 118 | IconButton(onClick = { /* do something*/ }) { 119 | Icon(imageVector = Icons.Filled.Menu, contentDescription = "Open Menu") 120 | } 121 | }, 122 | actions = { 123 | IconButton(onClick = { /* do something*/ }) { 124 | Icon(imageVector = Icons.Filled.Favorite, contentDescription = "Open Likes") 125 | } 126 | IconButton(onClick = { /* do something*/ }) { 127 | Icon(imageVector = Icons.Filled.Settings, contentDescription = "Open Settings") 128 | } 129 | } 130 | ) 131 | } 132 | 133 | @OptIn(ExperimentalMaterial3Api::class) 134 | @Composable 135 | fun LargeTopAppBarM3( 136 | scrollBehavior: TopAppBarScrollBehavior 137 | ) { 138 | LargeTopAppBar( 139 | scrollBehavior = scrollBehavior, 140 | title = { 141 | Text( 142 | text = "Banff National Park Trails", 143 | maxLines = 1, 144 | overflow = TextOverflow.Ellipsis 145 | ) 146 | }, 147 | navigationIcon = { 148 | IconButton(onClick = { /* do something*/ }) { 149 | Icon(imageVector = Icons.Filled.Menu, contentDescription = "Open Menu") 150 | } 151 | }, 152 | actions = { 153 | IconButton(onClick = { /* do something*/ }) { 154 | Icon(imageVector = Icons.Filled.Favorite, contentDescription = "Open Likes") 155 | } 156 | IconButton(onClick = { /* do something*/ }) { 157 | Icon(imageVector = Icons.Filled.Settings, contentDescription = "Open Settings") 158 | } 159 | IconButton(onClick = { /* do something*/ }) { 160 | Icon(imageVector = Icons.Filled.MoreVert, contentDescription = "Open Options") 161 | } 162 | } 163 | ) 164 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple80 = Color(0xFFD0BCFF) 6 | val PurpleGrey80 = Color(0xFFCCC2DC) 7 | val Pink80 = Color(0xFFEFB8C8) 8 | 9 | val Purple40 = Color(0xFF6650a4) 10 | val PurpleGrey40 = Color(0xFF625b71) 11 | val Pink40 = Color(0xFF7D5260) -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components.ui.theme 2 | 3 | import android.app.Activity 4 | import android.os.Build 5 | import androidx.compose.foundation.isSystemInDarkTheme 6 | import androidx.compose.material3.MaterialTheme 7 | import androidx.compose.material3.darkColorScheme 8 | import androidx.compose.material3.dynamicDarkColorScheme 9 | import androidx.compose.material3.dynamicLightColorScheme 10 | import androidx.compose.material3.lightColorScheme 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.runtime.SideEffect 13 | import androidx.compose.ui.graphics.toArgb 14 | import androidx.compose.ui.platform.LocalContext 15 | import androidx.compose.ui.platform.LocalView 16 | import androidx.core.view.WindowCompat 17 | 18 | private val DarkColorScheme = darkColorScheme( 19 | primary = Purple80, 20 | secondary = PurpleGrey80, 21 | tertiary = Pink80 22 | ) 23 | 24 | private val LightColorScheme = lightColorScheme( 25 | primary = Purple40, 26 | secondary = PurpleGrey40, 27 | tertiary = Pink40 28 | 29 | /* Other default colors to override 30 | background = Color(0xFFFFFBFE), 31 | surface = Color(0xFFFFFBFE), 32 | onPrimary = Color.White, 33 | onSecondary = Color.White, 34 | onTertiary = Color.White, 35 | onBackground = Color(0xFF1C1B1F), 36 | onSurface = Color(0xFF1C1B1F), 37 | */ 38 | ) 39 | 40 | @Composable 41 | fun Material3ComponentsTheme( 42 | darkTheme: Boolean = isSystemInDarkTheme(), 43 | // Dynamic color is available on Android 12+ 44 | dynamicColor: Boolean = true, 45 | content: @Composable () -> Unit 46 | ) { 47 | val colorScheme = when { 48 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { 49 | val context = LocalContext.current 50 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) 51 | } 52 | 53 | darkTheme -> DarkColorScheme 54 | else -> LightColorScheme 55 | } 56 | val view = LocalView.current 57 | if (!view.isInEditMode) { 58 | SideEffect { 59 | val window = (view.context as Activity).window 60 | window.statusBarColor = colorScheme.primary.toArgb() 61 | WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme 62 | } 63 | } 64 | 65 | MaterialTheme( 66 | colorScheme = colorScheme, 67 | typography = Typography, 68 | content = content 69 | ) 70 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/material3components/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package com.example.material3components.ui.theme 2 | 3 | import androidx.compose.material3.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | // Set of Material typography styles to start with 10 | val Typography = Typography( 11 | bodyLarge = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp, 15 | lineHeight = 24.sp, 16 | letterSpacing = 0.5.sp 17 | ) 18 | /* Other default text styles to override 19 | titleLarge = TextStyle( 20 | fontFamily = FontFamily.Default, 21 | fontWeight = FontWeight.Normal, 22 | fontSize = 22.sp, 23 | lineHeight = 28.sp, 24 | letterSpacing = 0.sp 25 | ), 26 | labelSmall = TextStyle( 27 | fontFamily = FontFamily.Default, 28 | fontWeight = FontWeight.Medium, 29 | fontSize = 11.sp, 30 | lineHeight = 16.sp, 31 | letterSpacing = 0.5.sp 32 | ) 33 | */ 34 | ) -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_visibility.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_visibility_off.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeInKotLang/Material_3_Components/214a375cebad58d16a84eddd51e25b3b133f8d89/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Material 3 Components 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |