Skip to content
Merged
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
27 changes: 2 additions & 25 deletions Jetcaster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Jetcaster sample 🎙️

Jetcaster is a sample podcast app, built with [Jetpack Compose][compose]. The goal of the sample is to
showcase dynamic theming and full featured architecture.
showcase building with Compose across multiple form factors and full featured architecture.

To try out this sample app, use the latest stable version
of [Android Studio](https://developer.android.com/studio).
Expand All @@ -14,7 +14,7 @@ project from Android Studio following the steps
### Status: 🚧 In progress 🚧

Jetcaster is still in the early stages of development, and as such only one screen has been created so far. However,
most of the app's architecture has been implemented, as well as the data layer, and early stages of dynamic theming.
most of the app's architecture has been implemented as well as the data layer.


## Screenshots
Expand All @@ -36,29 +36,6 @@ The player screen layout is adapting to different form factors, including a tabl

<img src="docs/tabletop.png"/>

### Dynamic theming
The home screen currently implements dynamic theming, using the artwork of the currently selected podcast from the carousel to update the `primary` and `onPrimary` [colors](https://developer.android.com/reference/kotlin/androidx/compose/material/Colors). You can see it in action in the screenshots above: as the carousel item is changed, the background gradient is updated to match the artwork.

This is implemented in [`DynamicTheming.kt`](app/src/main/java/com/example/jetcaster/util/DynamicTheming.kt), which provides the `DynamicThemePrimaryColorsFromImage` composable, to automatically animate the theme colors based on the provided image URL, like so:

``` kotlin
val dominantColorState: DominantColorState = rememberDominantColorState()

DynamicThemePrimaryColorsFromImage(dominantColorState) {
var imageUrl = remember { mutableStateOf("") }

// When the image url changes, call updateColorsFromImageUrl()
launchInComposition(imageUrl) {
dominantColorState.updateColorsFromImageUrl(imageUrl)
}

// Content which will be dynamically themed....
}
```

Underneath, [`DominantColorState`](app/src/main/java/com/example/jetcaster/util/DynamicTheming.kt) uses the [Coil][coil] library to fetch the artwork image 🖼️, and then [Palette][palette] to extract the dominant colors from the image 🎨.


### Others
Some other notable things which are implemented:

Expand Down
3 changes: 1 addition & 2 deletions Jetcaster/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ dependencies {
implementation(libs.androidx.constraintlayout.compose)

implementation(libs.androidx.compose.foundation)
implementation(libs.androidx.compose.material)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.materialWindow)
implementation(libs.androidx.compose.material3.window)
implementation(libs.androidx.compose.material.iconsExtended)
implementation(libs.androidx.compose.ui.tooling.preview)
debugImplementation(libs.androidx.compose.ui.tooling)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

package com.example.jetcaster.ui

import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@

package com.example.jetcaster.ui

import android.graphics.Color
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
Expand All @@ -32,10 +30,7 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

enableEdgeToEdge(
// This app is only ever in dark mode, so hard code detectDarkMode to true.
SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT, detectDarkMode = { true })
)
enableEdgeToEdge()

setContent {
val windowSizeClass = calculateWindowSizeClass(this)
Expand Down
Loading