Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,19 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: set up JDK 11
uses: actions/setup-java@v1
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: 11
- uses: actions/cache@v1
distribution: 'temurin'
java-version: '17'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Accept licenses and install SDK components
run: |
yes | sdkmanager --licenses
sdkmanager "platform-tools" "platforms;android-35" "build-tools;35.0.0"
- uses: actions/cache@v4
with:
path: ~/.gradle/caches
# Key inspired from here -
Expand All @@ -30,20 +37,21 @@ jobs:
run: ./gradlew test --stacktrace

ui-testing:
runs-on: macos-10.15
runs-on: macos-latest
strategy:
matrix:
api-level: [26, 28, 29]
target: [default, google_apis]
steps:
- uses: actions/checkout@v2
- name: set up JDK 11
uses: actions/setup-java@v1
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: 11
distribution: 'temurin'
java-version: '17'
- name: Checkout Branch
uses: actions/checkout@v2
- uses: actions/cache@v1
uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: ~/.gradle/caches
# Key inspired from here -
Expand Down
41 changes: 36 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,42 @@ I've also used the examples listed in this repo and given talks at conferences.

Setup
-----
To try out this sample app, you need to at least use the latest version
of Android Studio. This project has been tested against Android Studio Artic Fox.
[You can download it here](https://developer.android.com/studio/preview).
In general, Jetpack Compose requires you to use the Canary version of
Android Studio.
This project targets the latest stable Android tooling and Jetpack Compose APIs.

- Android Studio: Use the latest stable Android Studio (Hedgehog++/Koala or newer).
- Gradle: Wrapper is pinned to 8.7.
- Android Gradle Plugin: 8.5.x.
- Kotlin: 2.0.x with Compose compiler plugin.
- Compile SDK: 35. Min SDK: 21. Target SDK: 35.

Quick start:

1. Open the project in Android Studio (latest stable).
2. Let Gradle sync. If the Android SDK path isn't configured, set it in local.properties:

```
sdk.dir=/absolute/path/to/Android/Sdk
```

3. Build and run the `app` configuration.

Key build changes (2025):

- Uses Compose BOM to align Compose artifacts. Example in `app/build.gradle`:

```
dependencies {
implementation platform("androidx.compose:compose-bom:2025.04.01")
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.foundation:foundation"
implementation "androidx.compose.material3:material3"
debugImplementation "androidx.compose.ui:ui-tooling"
}
```

- Applies the Compose compiler via Kotlin plugin and targets Java 17 toolchain.
- Migrated to AGP 8 DSL with `namespace` and `packaging { resources { excludes } }`.
- Launcher activity is marked `android:exported="true"` to satisfy targetSdk 35.

Examples
-----------------
Expand Down
104 changes: 46 additions & 58 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.compose'
}

android {
compileSdkVersion 32
namespace 'com.example.jetpackcompose'
compileSdk 35

defaultConfig {
applicationId "com.example.jetpackcomposeplayground"
minSdkVersion 21
targetSdkVersion 30
minSdk 21
targetSdk 35
versionCode 1
versionName "1.0"

Expand All @@ -21,78 +25,62 @@ android {
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '11'
jvmTarget = '17'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerVersion "${versions.kotlinCompilerVersion}"
kotlinCompilerExtensionVersion "${versions.compose}"

}
packagingOptions {
packaging {
resources {
excludes += ['META-INF/AL2.0', 'META-INF/LGPL2.1']
}
}
packagingOptions {
resources {
excludes += ['META-INF/AL2.0', 'META-INF/LGPL2.1']
}
}

// Added to avoid this error -
// Execution failed for task ':app:mergeDebugAndroidTestJavaResource'.
// > A failure occurred while executing com.android.build.gradle.internal.tasks.MergeJavaResWorkAction
// > 2 files found with path 'META-INF/AL2.0' from inputs:
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

// Kotlin
implementation deps.kotlinStdLib
implementation platform('androidx.compose:compose-bom:2024.10.00')

// Support Libraries
implementation deps.support.appCompat
implementation deps.support.ktx
implementation deps.support.ktxViewModel
implementation deps.support.ktxLiveData
implementation deps.support.lifecycleExtensions
// Core Compose
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.foundation:foundation'
implementation 'androidx.compose.ui:ui-tooling-preview'
debugImplementation 'androidx.compose.ui:ui-tooling'
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
debugImplementation 'androidx.compose.ui:ui-test-manifest'

// CardView
implementation deps.cardView
// Material 3
implementation 'androidx.compose.material3:material3'
// Material 2 (for existing samples)
implementation 'androidx.compose.material:material'

// Constraint Layout
implementation deps.constraintLayout
// Compose integrations
implementation 'androidx.activity:activity-compose:1.9.3'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.8.6'
implementation 'androidx.compose.runtime:runtime-livedata'
implementation 'androidx.navigation:navigation-compose:2.8.1'
implementation 'androidx.constraintlayout:constraintlayout-compose:1.0.1'

// Coroutine
implementation deps.coroutine.core
// AndroidX core/support
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.core:core-ktx:1.13.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.6'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.6'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

// Compose
implementation deps.compose.activityCompose
implementation deps.compose.composeRuntime
implementation deps.compose.constraintLayout
implementation deps.compose.composeNavigation
implementation deps.compose.core
implementation deps.compose.foundation
implementation deps.compose.tooling
implementation deps.compose.layout
implementation deps.compose.material
implementation deps.compose.savedInstanceState
implementation deps.compose.uiLiveData
androidTestImplementation deps.compose.composeNavigationTest
androidTestImplementation deps.compose.uiTest
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1'

// Image loading
implementation deps.imageLoading.picasso
implementation deps.imageLoading.glideCore
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.github.bumptech.glide:glide:4.16.0'

testImplementation deps.test.junit
androidTestImplementation deps.test.junitImplementation
// Tests
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test:runner:1.5.2'
}
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".core.MainActivity">
<activity android:name=".core.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.runtime.Composable
Expand All @@ -36,7 +36,7 @@ import com.example.jetpackcompose.core.colors
import com.example.jetpackcompose.core.getPersonList

class ListAnimationActivity : AppCompatActivity() {
@ExperimentalAnimationApi
@OptIn(ExperimentalAnimationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Expand All @@ -49,7 +49,7 @@ class ListAnimationActivity : AppCompatActivity() {
// functions can only be called from within the scope of other composable functions. We should
// think of composable functions to be similar to lego blocks - each composable function is in turn
// built up of smaller composable functions.
@ExperimentalAnimationApi
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun ListAnimationComponent(personList: List<Person>) {
// Reacting to state changes is the core behavior of Compose. You will notice a couple new
Expand Down Expand Up @@ -108,12 +108,12 @@ fun ListAnimationComponent(personList: List<Person>) {
Card(
shape = RoundedCornerShape(4.dp),
backgroundColor = colors[index % colors.size],
modifier = Modifier.fillParentMaxWidth()
modifier = Modifier.fillMaxWidth()
) {
// Row is a composable that places its children in a horizontal sequence. You
// can think of it similar to a LinearLayout with the horizontal orientation.
Row(
modifier = Modifier.fillParentMaxWidth(),
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
// Text is a predefined composable that does exactly what you'd expect it to -
Expand Down Expand Up @@ -155,7 +155,7 @@ fun ListAnimationComponent(personList: List<Person>) {
* function that doesn't take any parameters and call your composable function with the appropriate
* params. Also, don't forget to annotate it with @Preview & @Composable annotations.
*/
@ExperimentalAnimationApi
@OptIn(ExperimentalAnimationApi::class)
@Preview
@Composable
fun ListAnimationComponentPreview() {
Expand Down
Loading
Loading