Reputation: 3689
We have a View based Android app with some drawables in res/drawable
folder, and their counterpart for night mode in res/drawable-night
folder
When using legacy views, referencing a drawable R.drawable.foo
from a XML layout file, the system would pick the drawable from either res/drawable
or res/drawable-night
folders depending on whether we are in day or night mode.
When using jetpack compose, we reference the drawable in an Image composable like this:
Image(painter = painterResource(R.drawable.foo))
However, this always pick the drawable from res/drawable
folder, ignoring day / night mode.
We could do something like this to select the right drawable, but we would need to test the night mode (isSystemInDarkTheme()
) within all composables that uses drawables depending on nigh mode:
Image(painter = painterResource(id = if (isSystemInDarkTheme()) R.drawable.foo_dark else R.drawable.foo_light))
Is there a way in compose to ensure that the drawable from day or night mode are picked correctly, and transpartently, as in legacy view system?
Upvotes: 8
Views: 2636
Reputation: 673
Maybe Compose was updated since the other answers were posted, but I can confirm that in a simple app using only Compose and two drawables with the same name in drawable
and drawable-night
folders, the app is picking up the dark one, if the phone is set to dark mode.
That's also without a composable theme defined, so this simple code does the job:
@Preview
@Preview(uiMode = UI_MODE_NIGHT_YES)
@Composable
fun ImagePreview() {
Image(
painter = painterResource(id = R.drawable.my_icon),
contentDescription = null
)
}
Note that you can also see this in a Preview - having two @Preview
annotations produces two previews in Android Studio, and specifying that you want to see your composable in dark mode is also possible!
Upvotes: 8
Reputation: 2958
As of now, "NO".
/drawable-night
?Google
provided support for some basic compose utils through Accompanist which does not come with standard Jetpack Compose. For example, PagerLayout, Swipe Refresh and many more.
One of those utils is Drawable Painter and that is something you can use.
After you add dependency, you can use this util using:
@Composable
fun DrawDrawable() {
val drawable = AppCompatResources.getDrawable(LocalContext.current, R.drawable.foo)
Image(
painter = rememberDrawablePainter(drawable = drawable),
contentDescription = "content description",
)
}
Note: Don't expect dark variant of the drawable to show up in @Preview. But it will be loaded at runtime.
Upvotes: 0
Reputation: 7602
Seeing how the dark & light palette is currently implemented in the theming codelab I'd go with creating my own somewhat similar abstraction:
class LightDrawables: Drawables
class DarkDrawables: Drawables
fun getDrawable(darkTheme: Boolean = isSystemInDarkTheme(), @DrawableRes drawableRes: Int) = if(darkTheme) DarkDrawables.xy else LightDrawables.xy
Upvotes: 0