diff --git a/app/build.gradle b/app/build.gradle index 75677b5..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,15 +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.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 187ee32..7ad4764 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -1,50 +1,188 @@ 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.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable +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 import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme +/** + * Note: LazyColumn and LazyRow are equivalent to RecyclerView in Android Views. + + * 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) setContent { - JetPackComposeBasicTheme { + JetPackComposeBasicTheme(dynamicColor = false) { // 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 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. -***/ + +@Composable +fun MyApp(modifier: Modifier = Modifier) { + /** 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) { + OnboardingScreen(onContinueClicked = { shouldShowOnboarding = false }) + } else { + Greetings() + } + } +} + @Composable fun Greeting(name: String) { - Text(text = "Hello $name!") + Card( + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.primary + ), + modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) + ) { + 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 = ("Composem ipsum color sit lazy, " + + "padding theme elit, sed do bouncy. ").repeat(4), + ) + } + } + 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) + } + ) + } + } +} + +@Composable +private fun Greetings( + modifier: Modifier = Modifier, + names: List = List(1000) { "item $it" } +) { + LazyColumn(modifier = modifier.padding(vertical = 4.dp)) { + items(items = names) { name -> + Greeting(name = name) + } + } } -@Preview(showBackground = true) +// 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, widthDp = 320) @Composable fun DefaultPreview() { + 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() + } +} + +@Preview(showBackground = true, widthDp = 320, heightDp = 320) +@Composable +fun OnboardingPreview() { + JetPackComposeBasicTheme { + OnboardingScreen(onContinueClicked = {}) + } +} + +@Preview +@Composable +fun MyAppPreview() { JetPackComposeBasicTheme { - Greeting("Android") + MyApp(Modifier.fillMaxSize()) } } \ No newline at end of file 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 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 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