diff --git a/.idea/other.xml b/.idea/other.xml
new file mode 100644
index 0000000..4604c44
--- /dev/null
+++ b/.idea/other.xml
@@ -0,0 +1,252 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 5cf5e0d..c6c2d08 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,24 @@
-# Compose Sample
-This simple app shows how to create a chat screen in compose this repo is bases on compose basic in official android page
+# Compose Code Examples
+In this repository you can find multiple basic compose codelab app samples all
+samples are divided into corresponding branches.
-### Note 👀
+### code-along-demo
-**This App doesn't focus on Building Modern Material Ui the UI looks clean**
\ No newline at end of file
+**In this branch we build very simple ```Scrollable List using LazyColumn with animation``` in compose Link to
+official [Compose Tutorial](https://developer.android.com/develop/ui/compose/tutorial)**
+
+
+
+### compose-layout
+
+**In this branch we will learn how to build a ```complex layouts``` in compose
+Link to official [codelab](https://developer.android.com/codelabs/jetpack-compose-layouts)**
+
+
+
+### compose-state
+
+**In this branch we will digger deeper into ```compose state``` Link to
+official [codelab](https://developer.android.com/codelabs/jetpack-compose-state)**
+
+
\ No newline at end of file
diff --git a/Screenshots/compose_layout.png b/Screenshots/compose_layout.png
new file mode 100644
index 0000000..8d34d99
Binary files /dev/null and b/Screenshots/compose_layout.png differ
diff --git a/Screenshots/scrollable_list.png b/Screenshots/scrollable_list.png
new file mode 100644
index 0000000..4402dd9
Binary files /dev/null and b/Screenshots/scrollable_list.png differ
diff --git a/Screenshots/state_in_compose.png b/Screenshots/state_in_compose.png
new file mode 100644
index 0000000..139fc55
Binary files /dev/null and b/Screenshots/state_in_compose.png differ
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 76eeaf8..3ee86a0 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,6 +1,7 @@
plugins {
- id("com.android.application")
- id("org.jetbrains.kotlin.android")
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.jetbrains.kotlin.android)
+ alias(libs.plugins.kotlin.serialization)
}
android {
@@ -9,7 +10,7 @@ android {
defaultConfig {
applicationId = "com.example.composeexample"
- minSdk = 24
+ minSdk = 21
targetSdk = 34
versionCode = 1
versionName = "1.0"
@@ -51,19 +52,34 @@ android {
dependencies {
- implementation("androidx.core:core-ktx:1.12.0")
- implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
- implementation("androidx.activity:activity-compose:1.8.2")
- implementation(platform("androidx.compose:compose-bom:2023.08.00"))
- implementation("androidx.compose.ui:ui")
- implementation("androidx.compose.ui:ui-graphics")
- implementation("androidx.compose.ui:ui-tooling-preview")
- implementation("androidx.compose.material3:material3")
- testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.5")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
- androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
- androidTestImplementation("androidx.compose.ui:ui-test-junit4")
- debugImplementation("androidx.compose.ui:ui-tooling")
- debugImplementation("androidx.compose.ui:ui-test-manifest")
-}
\ No newline at end of file
+ // Core UI
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.activity.compose)
+ implementation(platform(libs.androidx.compose.bom))
+ implementation(libs.androidx.ui)
+ implementation(libs.androidx.ui.graphics)
+ implementation(libs.androidx.ui.tooling.preview)
+ implementation(libs.androidx.material3)
+
+ // Unit Test
+ testImplementation(libs.junit)
+
+ // Compose Navigation
+ implementation(libs.androidx.navigation.compose)
+
+ // Kotlinx-Serialization
+ implementation(libs.kotlinx.serialization.json)
+
+ // Material Icon extended
+ implementation(libs.androidx.material.icons.extended)
+
+ // Instrumental Test
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(platform(libs.androidx.compose.bom))
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.ui.test.junit4)
+
+ debugImplementation(libs.androidx.ui.tooling)
+ debugImplementation(libs.androidx.ui.test.manifest)
+}
diff --git a/app/src/main/java/com/example/composeexample/MainActivity.kt b/app/src/main/java/com/example/composeexample/MainActivity.kt
index 0e40311..e7cedb7 100644
--- a/app/src/main/java/com/example/composeexample/MainActivity.kt
+++ b/app/src/main/java/com/example/composeexample/MainActivity.kt
@@ -1,143 +1,64 @@
package com.example.composeexample
-import android.content.res.Configuration
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
-import androidx.compose.animation.animateColorAsState
-import androidx.compose.animation.animateContentSize
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.border
-import androidx.compose.foundation.clickable
+import androidx.activity.enableEdgeToEdge
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
+import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import com.example.composeexample.data.SampleData
+import androidx.compose.ui.unit.sp
import com.example.composeexample.ui.theme.ComposeExampleTheme
+/** CompositionLocal allows you to create tree-scoped named objects that can be used as an implicit way of passing data to the composable UI tree
+ * rather than passing data explicitly to those composable that want data by using composable function
+ * parameters */
+
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
setContent {
ComposeExampleTheme {
- Surface(
- Modifier.fillMaxSize()
- ) {
- // MessageCard(message = Message("Mbyt", "developer"))
- Conversation(message = SampleData.conversationSample)
- }
- }
- }
- }
-}
-
-data class Message(val author: String, val body: String)
-
-@Composable
-fun MessageCard(message: Message) {
-
- Row(Modifier.padding(all = 8.dp)) {
- Image(
- painter = painterResource(id = R.drawable.nature_pic),
- contentDescription = "userImage",
- modifier = Modifier
- .size(60.dp)
- .clip(CircleShape)
- .border(
- 1.5.dp,
- MaterialTheme.colorScheme.inversePrimary,
- MaterialTheme.shapes.medium
- ),
- contentScale = ContentScale.FillWidth,
-
- )
-
- var isExpanded by remember { mutableStateOf(false) }
- // surfaceColor will be updated gradually from one color to the other
- val surfaceColor by animateColorAsState(
- if (isExpanded) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surface,
- )
+ val system = if (isSystemInDarkTheme()) {
+ System("Dark Theme")
+ } else System("Light Theme") // conditionally change the value of the System
- Spacer(modifier = Modifier.size(12.dp))
-
- Column(Modifier.clickable { isExpanded = !isExpanded }){ // column place the child item in horizontal
- Text(
- text = message.author,
- color = MaterialTheme.colorScheme.primary,
- style = MaterialTheme.typography.titleSmall
- )
+ Scaffold {
+ CompositionLocalProvider(LocalSystem provides system) { // provides the conditionally changing (system) value to the key of the compositionLocal
+ SystemDetail(modifier = Modifier.padding(it))
+ }
+ }
- Surface(
- shape = MaterialTheme.shapes.medium,
- shadowElevation = 1.dp,
- // surfaceColor color will be changing gradually from primary to surface
- color = surfaceColor,
- // animateContentSize will change the Surface size gradually
- modifier = Modifier
- .animateContentSize()
- .padding(1.dp)
- ) {
- Text(
- text = message.body,
- maxLines = if (isExpanded) Int.MAX_VALUE else 1,
- modifier = Modifier.padding(4.dp),
- style = MaterialTheme.typography.bodyMedium
- )
}
-
- }
- }
-}
-
-@Preview("Light Mode")
-@Preview(
- uiMode = Configuration.UI_MODE_NIGHT_YES,
- showBackground = true,
- name = "Night mode"
-)
-@Composable
-fun PrevCard() {
- ComposeExampleTheme {
- Surface {
- MessageCard(message = Message("Mb", "Developer"))
}
-
}
}
@Composable
-fun Conversation(message: List) {
- LazyColumn {
- items(message) {
- MessageCard(message = it)
- }
+fun SystemDetail(modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier.fillMaxSize(),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text(text = LocalSystem.current.theme, fontSize = 20.sp)
}
}
-@Preview
+@Preview(showBackground = true)
@Composable
-fun PreviewConversation() {
- Surface {
- Conversation(message = SampleData.conversationSample)
+private fun UserDetailPreview() {
+ ComposeExampleTheme {
+ SystemDetail()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/composeexample/System.kt b/app/src/main/java/com/example/composeexample/System.kt
new file mode 100644
index 0000000..38260d0
--- /dev/null
+++ b/app/src/main/java/com/example/composeexample/System.kt
@@ -0,0 +1,12 @@
+package com.example.composeexample
+
+import androidx.compose.runtime.compositionLocalOf
+
+data class System(val theme: String = "Light")
+
+val LocalSystem = compositionLocalOf { System() } // must be declared in top level of the class/file so the composable can access it and also
+// providing default value is good practise that helps us to showing previews in the IDE and creating a test
+
+// TODO: here we using [compositionLocalOf] Changing the value here (isSystemInDarkTheme) invalidates only the content that reads its current value here the [Text composable].
+// TODO: by using [staticCompositionLocalOf] the reads are not tracked by composable, By changing in the value here conditionally (isSystemInDarkTheme) the entire content lambda in a CompositionLocalProvider]
+// will be recomposed instead of current value reads in a [compositionLocalOf]
\ No newline at end of file
diff --git a/app/src/main/java/com/example/composeexample/data/SampleData.kt b/app/src/main/java/com/example/composeexample/data/SampleData.kt
deleted file mode 100644
index 3447738..0000000
--- a/app/src/main/java/com/example/composeexample/data/SampleData.kt
+++ /dev/null
@@ -1,129 +0,0 @@
-package com.example.composeexample.data
-
-import com.example.composeexample.Message
-
-/**
- * SampleData for Jetpack Compose Tutorial
- */
-object SampleData {
- // Sample conversation data
- val conversationSample = listOf(
- Message(
- "Lexi",
- "Test...Test...Test..."
- ),
- Message(
- "Lexi",
- """List of Android versions:
- |Android KitKat (API 19)
- |Android Lollipop (API 21)
- |Android Marshmallow (API 23)
- |Android Nougat (API 24)
- |Android Oreo (API 26)
- |Android Pie (API 28)
- |Android 10 (API 29)
- |Android 11 (API 30)
- |Android 12 (API 31)""".trim()
- ),
- Message(
- "Lexi",
- """I think Kotlin is my favorite programming language.
- |It's so much fun!""".trim()
- ),
- Message(
- "Lexi",
- "Searching for alternatives to XML layouts..."
- ),
- Message(
- "Lexi",
- """Hey, take a look at Jetpack Compose, it's great!
- |It's the Android's modern toolkit for building native UI.
- |It simplifies and accelerates UI development on Android.
- |Less code, powerful tools, and intuitive Kotlin APIs :)""".trim()
- ),
- Message(
- "Lexi",
- "It's available from API 21+ :)"
- ),
- Message(
- "Lexi",
- "Writing Kotlin for UI seems so natural, Compose where have you been all my life?"
- ),
- Message(
- "Lexi",
- "Android Studio next version's name is Arctic Fox"
- ),
- Message(
- "Lexi",
- "Android Studio Arctic Fox tooling for Compose is top notch ^_^"
- ),
- Message(
- "Lexi",
- "I didn't know you can now run the emulator directly from Android Studio"
- ),
- Message(
- "Lexi",
- "Compose Previews are great to check quickly how a composable layout looks like"
- ),
- Message(
- "Lexi",
- "Previews are also interactive after enabling the experimental setting"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Have you tried writing build.gradle with KTS?"
- ),
- Message(
- "Lexi",
- "Kapt is deprecated"
- ),
- Message(
- "Android",
- "Have you tried writing build.gradle with KTS?"
- ),
- )
-}
diff --git a/app/src/main/java/com/example/composeexample/ui/theme/Theme.kt b/app/src/main/java/com/example/composeexample/ui/theme/Theme.kt
index 9e28e0b..9844874 100644
--- a/app/src/main/java/com/example/composeexample/ui/theme/Theme.kt
+++ b/app/src/main/java/com/example/composeexample/ui/theme/Theme.kt
@@ -26,15 +26,15 @@ private val LightColorScheme = lightColorScheme(
secondary = PurpleGrey40,
tertiary = Pink40
- /* Other default colors to override
+ /* // 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),
- */
+ onSurface = Color(0xFF1C1B1F),*/
+
)
@Composable
diff --git a/app/src/main/res/drawable/nature_pic.jpg b/app/src/main/res/drawable/nature_pic.jpg
deleted file mode 100644
index 091797a..0000000
Binary files a/app/src/main/res/drawable/nature_pic.jpg and /dev/null differ
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0edc2d4..7415591 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,14 @@
Compose Example
+ Show more
+ Show less
+ IOS Platform
+ Platform Independent
+ Programmer\'s Best friend
+ Game Development
+ JVM language
+ Data Science
+ Superset set of JS
+ Top languages
+ Most Popular
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 4645626..f74b04b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,5 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
- id("com.android.application") version "8.2.2" apply false
- id("org.jetbrains.kotlin.android") version "1.9.0" apply false
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.jetbrains.kotlin.android) apply false
}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 0000000..ea7eb38
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,37 @@
+[versions]
+agp = "8.4.0"
+kotlin = "1.9.0"
+coreKtx = "1.13.1"
+junit = "4.13.2"
+junitVersion = "1.1.5"
+espressoCore = "3.5.1"
+serializationVersion = "1.6.3"
+lifecycleRuntimeKtx = "2.8.0"
+activityCompose = "1.9.0"
+composeBom = "2023.08.00"
+navigationCompose = "2.8.0-beta02"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" }
+androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
+androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
+androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
+androidx-ui = { group = "androidx.compose.ui", name = "ui" }
+androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
+androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
+androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
+androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
+androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
+androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
+kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serializationVersion" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 135bd5f..7a0226b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Mon Feb 05 14:11:33 IST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists