From 33a11e210113df097e512d94b0b2e5a571bc3586 Mon Sep 17 00:00:00 2001 From: Kaushal-Vasava Date: Thu, 5 Jan 2023 11:47:50 +0530 Subject: [PATCH 1/8] Add Surface to Greeting composable to enhance UI --- .../com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index 187ee32..79878ac 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -28,6 +28,7 @@ class MainActivity : ComponentActivity() { } } } + /*** Composable functions : A composable function is a regular function annotated with @Composable. @@ -35,10 +36,12 @@ This enables your function to call other @Composable functions within it. You can see how the Greeting function is marked as @Composable. This function will produce a piece of UI hierarchy displaying the given input, String. Text is a composable function provided by the library. -***/ + ***/ @Composable fun Greeting(name: String) { - Text(text = "Hello $name!") + Surface(color = MaterialTheme.colorScheme.primary) { + Text(text = "Hello $name!") + } } @Preview(showBackground = true) From ec794aff20146d65e82c286887bfbba6ac10bf00 Mon Sep 17 00:00:00 2001 From: Kaushal-Vasava Date: Thu, 5 Jan 2023 12:04:16 +0530 Subject: [PATCH 2/8] Reused composable function --- .../apps/jetpackcomposebasic/MainActivity.kt | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index 79878ac..c5b5990 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -4,6 +4,7 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -18,17 +19,22 @@ class MainActivity : ComponentActivity() { setContent { JetPackComposeBasicTheme { // A surface container using the 'background' color from the theme - Surface( - modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.background - ) { - Greeting("Android") - } + MyApp(modifier = Modifier.fillMaxSize()) } } } } +@Composable +fun MyApp(modifier: Modifier = Modifier) { + Surface( + modifier = modifier, + color = MaterialTheme.colorScheme.background + ) { + Greeting("Android") + } +} + /*** Composable functions : A composable function is a regular function annotated with @Composable. @@ -48,6 +54,6 @@ fun Greeting(name: String) { @Composable fun DefaultPreview() { JetPackComposeBasicTheme { - Greeting("Android") + MyApp() } } \ No newline at end of file From 845c667e9b68395b0598482fb044e3af7e6a0577 Mon Sep 17 00:00:00 2001 From: Kaushal-Vasava Date: Thu, 5 Jan 2023 12:37:51 +0530 Subject: [PATCH 3/8] Add Row, Column and Button composable --- .../apps/jetpackcomposebasic/MainActivity.kt | 58 ++++++++++++++----- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index c5b5990..0722d94 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -3,14 +3,12 @@ package com.lahsuak.apps.jetpackcomposebasic import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text +import androidx.compose.foundation.layout.* +import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme class MainActivity : ComponentActivity() { @@ -26,27 +24,55 @@ class MainActivity : ComponentActivity() { } @Composable -fun MyApp(modifier: Modifier = Modifier) { - Surface( - modifier = modifier, - color = MaterialTheme.colorScheme.background - ) { - Greeting("Android") +fun MyApp( + modifier: Modifier = Modifier, + names: List = listOf("World", "Kaushal") +) { + Column(modifier = modifier.padding(vertical = 4.dp)) { + for (name in names) { + Greeting(name) + } } } -/*** -Composable functions : +/** + * Composable functions : A composable function is a regular function annotated with @Composable. This enables your function to call other @Composable functions within it. You can see how the Greeting function is marked as @Composable. This function will produce a piece of UI hierarchy displaying the given input, String. Text is a composable function provided by the library. - ***/ + **/ + +/** + * 1. Column is Vertical linear layout of view system + * 2. Row is Horizontal linear layout of view system + * 3. Box is FrameLayout of view system + */ + +/** + * Button is a composable provided by the material3 package +which takes a composable as the last argument. +Since trailing lambdas can be moved outside of the parentheses, +you can add any content to the button as a child. For example, a Text + */ + @Composable fun Greeting(name: String) { - Surface(color = MaterialTheme.colorScheme.primary) { - Text(text = "Hello $name!") + Surface( + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) + ) { + Row(modifier = Modifier.padding(24.dp)) { + Column(modifier = Modifier.weight(1f)) { + Text(text = "Hello,") + Text(text = name) + } + ElevatedButton(onClick = { }) { + Text(text = "Show more") + } + } + } } From a9eef7ccec7e392cac9e2234cc7ca9d6699aec7d Mon Sep 17 00:00:00 2001 From: Kaushal-Vasava Date: Thu, 5 Jan 2023 14:11:42 +0530 Subject: [PATCH 4/8] Add handling of composable state and add onboarding screen with state hoisting --- .../apps/jetpackcomposebasic/MainActivity.kt | 125 +++++++++++++----- 1 file changed, 93 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index 0722d94..4aa5ca9 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -5,12 +5,24 @@ import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.* import androidx.compose.material3.* -import androidx.compose.runtime.Composable +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme +/** + * In Composable functions, state that is read or modified by multiple functions +should live in a common ancestor—this process is called state hoisting. +To hoist means to lift or elevate. + + * Making state hoistable avoids duplicating state and introducing bugs, +helps reuse composables, and makes composables substantially easier to test. +Contrarily, state that doesn't need to be controlled by a composable's parent should not be hoisted. +The source of truth belongs to whoever creates and controls that state. + **/ + class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -24,62 +36,111 @@ class MainActivity : ComponentActivity() { } @Composable -fun MyApp( - modifier: Modifier = Modifier, - names: List = listOf("World", "Kaushal") -) { - Column(modifier = modifier.padding(vertical = 4.dp)) { - for (name in names) { - Greeting(name) +fun MyApp(modifier: Modifier = Modifier) { + // shouldShowOnboarding is using a by keyword instead of the =. + // This is a property delegate that saves you from typing .value every time. + var shouldShowOnboarding by remember { mutableStateOf(true) } + + Surface(modifier) { + if (shouldShowOnboarding) { + OnboardingScreen(onContinueClicked = { shouldShowOnboarding = false }) + } else { + Greetings() } } } /** - * Composable functions : -A composable function is a regular function annotated with @Composable. -This enables your function to call other @Composable functions within it. -You can see how the Greeting function is marked as @Composable. -This function will produce a piece of UI hierarchy displaying the given input, -String. Text is a composable function provided by the library. - **/ - -/** - * 1. Column is Vertical linear layout of view system - * 2. Row is Horizontal linear layout of view system - * 3. Box is FrameLayout of view system - */ - -/** - * Button is a composable provided by the material3 package -which takes a composable as the last argument. -Since trailing lambdas can be moved outside of the parentheses, -you can add any content to the button as a child. For example, a Text + * "State" and "MutableState" are interfaces that hold some value +and trigger UI updates (recompositions) whenever that value changes. +However you can't just assign mutableStateOf to a variable inside a composable. + * As explained before, recomposition can happen at any time which would call the composable again, +resetting the state to a new mutable state with a value of false. + * To preserve state across recompositions, remember the mutable state using "remember". +remember is used to guard against recomposition, so the state is not reset. */ @Composable fun Greeting(name: String) { + val expanded = remember { mutableStateOf(false) } + + val extraPadding = if (expanded.value) 48.dp else 0.dp + Surface( color = MaterialTheme.colorScheme.primary, modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) ) { Row(modifier = Modifier.padding(24.dp)) { - Column(modifier = Modifier.weight(1f)) { + Column( + modifier = Modifier + .weight(1f) + .padding(bottom = extraPadding) + ) { Text(text = "Hello,") Text(text = name) } - ElevatedButton(onClick = { }) { - Text(text = "Show more") + ElevatedButton( + onClick = { expanded.value = !expanded.value } + ) { + Text(if (expanded.value) "Show less" else "Show more") } } + } +} + +@Composable +private fun Greetings( + modifier: Modifier = Modifier, + names: List = listOf("World", "Kaushal") +) { + Column(modifier = modifier.padding(vertical = 4.dp)) { + for (name in names) { + Greeting(name = name) + } + } +} +// add new on-boarding screen +@Composable +fun OnboardingScreen( + onContinueClicked: () -> Unit, + modifier: Modifier = Modifier +) { + Column( + modifier = modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text("Welcome to the Basics Codelab!") + Button( + modifier = Modifier.padding(vertical = 24.dp), + onClick = onContinueClicked + ) { + Text("Continue") + } } } -@Preview(showBackground = true) +@Preview(showBackground = true, widthDp = 320) @Composable fun DefaultPreview() { JetPackComposeBasicTheme { - MyApp() + Greetings() + } +} + +@Preview(showBackground = true, widthDp = 320, heightDp = 320) +@Composable +fun OnboardingPreview() { + JetPackComposeBasicTheme { + OnboardingScreen(onContinueClicked = {}) + } +} + +@Preview +@Composable +fun MyAppPreview() { + JetPackComposeBasicTheme { + MyApp(Modifier.fillMaxSize()) } } \ No newline at end of file From 0017805d687d925d617c605805215b18b184a3a5 Mon Sep 17 00:00:00 2001 From: Kaushal-Vasava Date: Thu, 5 Jan 2023 14:36:48 +0530 Subject: [PATCH 5/8] Add lazy column and add state persistent logic --- .../apps/jetpackcomposebasic/MainActivity.kt | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index 4aa5ca9..f16b4b6 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -4,8 +4,11 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview @@ -13,16 +16,11 @@ import androidx.compose.ui.unit.dp import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme /** - * In Composable functions, state that is read or modified by multiple functions -should live in a common ancestor—this process is called state hoisting. -To hoist means to lift or elevate. + * Note: LazyColumn and LazyRow are equivalent to RecyclerView in Android Views. - * Making state hoistable avoids duplicating state and introducing bugs, -helps reuse composables, and makes composables substantially easier to test. -Contrarily, state that doesn't need to be controlled by a composable's parent should not be hoisted. -The source of truth belongs to whoever creates and controls that state. + * To display a scrollable column we use a LazyColumn. +-> LazyColumn renders only the visible items on screen, allowing performance gains when rendering a big list. **/ - class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -37,9 +35,11 @@ class MainActivity : ComponentActivity() { @Composable fun MyApp(modifier: Modifier = Modifier) { - // shouldShowOnboarding is using a by keyword instead of the =. - // This is a property delegate that saves you from typing .value every time. - var shouldShowOnboarding by remember { mutableStateOf(true) } + /** PERSISTENT STATE + * Instead of using remember you can use rememberSaveable. + This will save each state surviving configuration changes (such as rotations) and process death. + **/ + var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) } Surface(modifier) { if (shouldShowOnboarding) { @@ -50,21 +50,11 @@ fun MyApp(modifier: Modifier = Modifier) { } } -/** - * "State" and "MutableState" are interfaces that hold some value -and trigger UI updates (recompositions) whenever that value changes. -However you can't just assign mutableStateOf to a variable inside a composable. - * As explained before, recomposition can happen at any time which would call the composable again, -resetting the state to a new mutable state with a value of false. - * To preserve state across recompositions, remember the mutable state using "remember". -remember is used to guard against recomposition, so the state is not reset. - */ - @Composable fun Greeting(name: String) { - val expanded = remember { mutableStateOf(false) } + var expanded by rememberSaveable { mutableStateOf(false) } - val extraPadding = if (expanded.value) 48.dp else 0.dp + val extraPadding = if (expanded) 48.dp else 0.dp Surface( color = MaterialTheme.colorScheme.primary, @@ -80,9 +70,9 @@ fun Greeting(name: String) { Text(text = name) } ElevatedButton( - onClick = { expanded.value = !expanded.value } + onClick = { expanded = !expanded } ) { - Text(if (expanded.value) "Show less" else "Show more") + Text(if (expanded) "Show less" else "Show more") } } } @@ -91,10 +81,10 @@ fun Greeting(name: String) { @Composable private fun Greetings( modifier: Modifier = Modifier, - names: List = listOf("World", "Kaushal") + names: List = List(1000) { "item $it" } ) { - Column(modifier = modifier.padding(vertical = 4.dp)) { - for (name in names) { + LazyColumn(modifier = modifier.padding(vertical = 4.dp)) { + items(items = names) { name -> Greeting(name = name) } } From f99d8196c0e4209080202b876c60838d2fe37436 Mon Sep 17 00:00:00 2001 From: Kaushal-Vasava Date: Thu, 5 Jan 2023 15:17:28 +0530 Subject: [PATCH 6/8] Add Animaztion and change light and dark themes --- .../apps/jetpackcomposebasic/MainActivity.kt | 41 +++++++++++++++---- .../jetpackcomposebasic/ui/theme/Color.kt | 7 +++- .../jetpackcomposebasic/ui/theme/Theme.kt | 25 ++++------- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index f16b4b6..7561269 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -1,8 +1,10 @@ package com.lahsuak.apps.jetpackcomposebasic +import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.animation.core.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items @@ -11,6 +13,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme @@ -25,7 +28,7 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { - JetPackComposeBasicTheme { + JetPackComposeBasicTheme(dynamicColor = false) { // A surface container using the 'background' color from the theme MyApp(modifier = Modifier.fillMaxSize()) } @@ -36,9 +39,9 @@ class MainActivity : ComponentActivity() { @Composable fun MyApp(modifier: Modifier = Modifier) { /** PERSISTENT STATE - * Instead of using remember you can use rememberSaveable. + * Instead of using remember you can use rememberSaveable. This will save each state surviving configuration changes (such as rotations) and process death. - **/ + **/ var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) } Surface(modifier) { @@ -54,7 +57,13 @@ fun MyApp(modifier: Modifier = Modifier) { fun Greeting(name: String) { var expanded by rememberSaveable { mutableStateOf(false) } - val extraPadding = if (expanded) 48.dp else 0.dp + val extraPadding by animateDpAsState( + if (expanded) 48.dp else 0.dp, + animationSpec = spring( + dampingRatio = Spring.DampingRatioMediumBouncy, + stiffness = Spring.StiffnessLow + ) + ) Surface( color = MaterialTheme.colorScheme.primary, @@ -64,10 +73,14 @@ fun Greeting(name: String) { Column( modifier = Modifier .weight(1f) - .padding(bottom = extraPadding) + .padding(bottom = extraPadding.coerceAtLeast(0.dp)) ) { Text(text = "Hello,") - Text(text = name) + Text( + text = name, style = MaterialTheme.typography.headlineMedium.copy( + fontWeight = FontWeight.ExtraBold + ) + ) } ElevatedButton( onClick = { expanded = !expanded } @@ -114,7 +127,21 @@ fun OnboardingScreen( @Preview(showBackground = true, widthDp = 320) @Composable fun DefaultPreview() { - JetPackComposeBasicTheme { + JetPackComposeBasicTheme(dynamicColor = false) { + Greetings() + } +} + +@Preview( + showBackground = true, + widthDp = 320, + uiMode = UI_MODE_NIGHT_YES, + name = "Dark" +) +@Preview(showBackground = true, widthDp = 320) +@Composable +fun DefaultPreviewDark() { + JetPackComposeBasicTheme(dynamicColor = false) { Greetings() } } diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/theme/Color.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/theme/Color.kt index e0a4930..69564a0 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/theme/Color.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/theme/Color.kt @@ -8,4 +8,9 @@ val Pink80 = Color(0xFFEFB8C8) val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) \ No newline at end of file +val Pink40 = Color(0xFF7D5260) + +val Navy = Color(0xFF073042) +val Blue = Color(0xFF4285F4) +val LightBlue = Color(0xFFD7EFFE) +val Chartreuse = Color(0xFFEFF7CF) \ No newline at end of file diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/theme/Theme.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/theme/Theme.kt index 5ec8f0d..b112dfd 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/theme/Theme.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/theme/Theme.kt @@ -10,31 +10,24 @@ import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView import androidx.core.view.ViewCompat private val DarkColorScheme = darkColorScheme( - primary = Purple80, - secondary = PurpleGrey80, - tertiary = Pink80 + surface = Blue, + onSurface = Navy, + primary = Navy, + onPrimary = Chartreuse ) private val LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 - - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ + surface = Blue, + onSurface = Color.White, + primary = LightBlue, + onPrimary = Navy ) @Composable From 8dae36d84ae75b0eb0cd9722636623c41dff213f Mon Sep 17 00:00:00 2001 From: Kaushal-Vasava Date: Thu, 5 Jan 2023 17:10:47 +0530 Subject: [PATCH 7/8] Add card composable and give it some animations --- app/build.gradle | 2 + .../apps/jetpackcomposebasic/MainActivity.kt | 78 ++++++++++++------- app/src/main/res/values/strings.xml | 2 + 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 75677b5..b925592 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -54,6 +54,8 @@ dependencies { implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.compose.material3:material3:1.1.0-alpha03' + implementation "androidx.compose.material:material-icons-extended:1.1.0" + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.4' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index 7561269..551f70f 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -4,15 +4,20 @@ import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.animation.animateContentSize import androidx.compose.animation.core.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ExpandLess +import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -55,38 +60,59 @@ fun MyApp(modifier: Modifier = Modifier) { @Composable fun Greeting(name: String) { - var expanded by rememberSaveable { mutableStateOf(false) } - - val extraPadding by animateDpAsState( - if (expanded) 48.dp else 0.dp, - animationSpec = spring( - dampingRatio = Spring.DampingRatioMediumBouncy, - stiffness = Spring.StiffnessLow - ) - ) - Surface( - color = MaterialTheme.colorScheme.primary, + Card( + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.primary + ), modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) ) { - Row(modifier = Modifier.padding(24.dp)) { - Column( - modifier = Modifier - .weight(1f) - .padding(bottom = extraPadding.coerceAtLeast(0.dp)) - ) { - Text(text = "Hello,") + CardContent(name) + } +} + +@Composable +fun CardContent(name: String) { + var expanded by rememberSaveable { mutableStateOf(false) } + + Row( + modifier = Modifier + .padding(12.dp) + .animateContentSize( + animationSpec = spring( + dampingRatio = Spring.DampingRatioMediumBouncy, + stiffness = Spring.StiffnessLow + ) + ) + ) { + Column( + modifier = Modifier + .weight(1f) + .padding(12.dp) + ) + { + Text(text = "Hello,") + Text( + text = name, style = MaterialTheme.typography.headlineMedium.copy( + fontWeight = FontWeight.ExtraBold + ) + ) + if (expanded) { Text( - text = name, style = MaterialTheme.typography.headlineMedium.copy( - fontWeight = FontWeight.ExtraBold - ) + text = ("Composem ipsum color sit lazy, " + + "padding theme elit, sed do bouncy. ").repeat(4), ) } - ElevatedButton( - onClick = { expanded = !expanded } - ) { - Text(if (expanded) "Show less" else "Show more") - } + } + IconButton(onClick = { expanded = !expanded }) { + Icon( + imageVector = if (expanded) Icons.Filled.ExpandLess else Icons.Filled.ExpandMore, + contentDescription = if (expanded) { + stringResource(R.string.show_less) + } else { + stringResource(R.string.show_more) + } + ) } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 17b9141..9b64c7f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ JetPackCompose Basic + Show less + Show more \ No newline at end of file From f49bc77cc215f66701b7d87fe376ac1aea09f2a5 Mon Sep 17 00:00:00 2001 From: KaushalVasava Date: Tue, 1 Aug 2023 11:36:28 +0530 Subject: [PATCH 8/8] Update dependencies --- app/build.gradle | 25 ++++++++++--------- .../apps/jetpackcomposebasic/MainActivity.kt | 1 - build.gradle | 8 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b925592..0654d2b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,12 +5,12 @@ plugins { android { namespace 'com.lahsuak.apps.jetpackcomposebasic' - compileSdk 33 + compileSdk 34 defaultConfig { applicationId "com.lahsuak.apps.jetpackcomposebasic" minSdk 23 - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" @@ -27,17 +27,17 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } buildFeatures { compose true } composeOptions { - kotlinCompilerExtensionVersion '1.1.1' + kotlinCompilerExtensionVersion '1.4.3' } packagingOptions { resources { @@ -48,17 +48,18 @@ android { dependencies { + //noinspection GradleDependency implementation 'androidx.core:core-ktx:1.9.0' - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' - implementation 'androidx.activity:activity-compose:1.6.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' + implementation 'androidx.activity:activity-compose:1.7.2' implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" - implementation 'androidx.compose.material3:material3:1.1.0-alpha03' - implementation "androidx.compose.material:material-icons-extended:1.1.0" + implementation 'androidx.compose.material3:material3:1.2.0-alpha03' + implementation "androidx.compose.material:material-icons-extended:1.4.3" testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.4' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index 551f70f..7ad4764 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -60,7 +60,6 @@ fun MyApp(modifier: Modifier = Modifier) { @Composable fun Greeting(name: String) { - Card( colors = CardDefaults.cardColors( containerColor = MaterialTheme.colorScheme.primary diff --git a/build.gradle b/build.gradle index e868fc8..b0f2f02 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,10 @@ buildscript { ext { - compose_version = '1.3.2' + compose_version = '1.4.3' } }// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '7.3.0' apply false - id 'com.android.library' version '7.3.0' apply false - id 'org.jetbrains.kotlin.android' version '1.6.10' apply false + id 'com.android.application' version '8.0.2' apply false + id 'com.android.library' version '8.0.2' apply false + id 'org.jetbrains.kotlin.android' version '1.8.10' apply false } \ No newline at end of file