zhanghai / composepreference Goto Github PK
View Code? Open in Web Editor NEWPreference implementation for Jetpack Compose Material 3
License: Apache License 2.0
Preference implementation for Jetpack Compose Material 3
License: Apache License 2.0
Updating dependency from lifecycle 2.7.0 to 2.8.0 would hopefully "just work".
https://developer.android.com/jetpack/androidx/releases/lifecycle#version_28_2
As soon as a screen with preferences from this library is used with updated lifecycle dependency the app crashed with the following stack trace example 1 with direct usage of rememberPreferenceState
:
java.lang.IllegalStateException: CompositionLocal LocalLifecycleOwner not present
at androidx.lifecycle.compose.LocalLifecycleOwnerKt$LocalLifecycleOwner$1.invoke(LocalLifecycleOwner.kt:26)
at androidx.lifecycle.compose.LocalLifecycleOwnerKt$LocalLifecycleOwner$1.invoke(LocalLifecycleOwner.kt:25)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at androidx.compose.runtime.LazyValueHolder.getCurrent(ValueHolders.kt:29)
at androidx.compose.runtime.LazyValueHolder.getValue(ValueHolders.kt:31)
at androidx.compose.runtime.CompositionLocalMapKt.read(CompositionLocalMap.kt:90)
at androidx.compose.runtime.ComposerImpl.consume(Composer.kt:2135)
at androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(FlowExt.kt:183)
at me.zhanghai.compose.preference.PreferenceStateKt.rememberPreferenceState(PreferenceState.kt:35)
...
Stack trace example 2 with indirect usage of rememberPreferenceState
using a listPreference
:
java.lang.IllegalStateException: CompositionLocal LocalLifecycleOwner not present
at androidx.lifecycle.compose.LocalLifecycleOwnerKt$LocalLifecycleOwner$1.invoke(LocalLifecycleOwner.kt:26)
at androidx.lifecycle.compose.LocalLifecycleOwnerKt$LocalLifecycleOwner$1.invoke(LocalLifecycleOwner.kt:25)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at androidx.compose.runtime.LazyValueHolder.getCurrent(ValueHolders.kt:29)
at androidx.compose.runtime.LazyValueHolder.getValue(ValueHolders.kt:31)
at androidx.compose.runtime.CompositionLocalMapKt.read(CompositionLocalMap.kt:90)
at androidx.compose.runtime.ComposerImpl.consume(Composer.kt:2135)
at androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(FlowExt.kt:183)
at me.zhanghai.compose.preference.PreferenceStateKt.rememberPreferenceState(PreferenceState.kt:35)
at se.consat.telematics.travelito.ui.screens.ComposableSingletons$AppSettingsScreenKt$lambda-21$1$1$invoke$$inlined$listPreference$default$1.invoke(ListPreference.kt:283)
at se.consat.telematics.travelito.ui.screens.ComposableSingletons$AppSettingsScreenKt$lambda-21$1$1$invoke$$inlined$listPreference$default$1.invoke(ListPreference.kt:80)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:118)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.foundation.lazy.LazyListIntervalContent$item$3.invoke(LazyListIntervalContent.kt:59)
Changing dependency back to 2.7.0 and it starts working fine again.
val lifecycle_version = "2.7.0" // https://developer.android.com/jetpack/androidx/releases/lifecycle
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
// ViewModel utilities for Compose
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version")
// LiveData
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
// Lifecycles only (without ViewModel or LiveData)
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version") //empty since 2.8.0+
// Lifecycle utilities for Compose
implementation("androidx.lifecycle:lifecycle-runtime-compose:$lifecycle_version")
// Saved state module for ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version")
// Annotation processor
//kapt("androidx.lifecycle:lifecycle-compiler:$lifecycle_version")
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
// optional - helpers for implementing LifecycleOwner in a Service
implementation("androidx.lifecycle:lifecycle-service:$lifecycle_version")
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation("androidx.lifecycle:lifecycle-process:$lifecycle_version")
Code example 1:
ProvidePreferenceLocals {
Column(...) {
val state: MutableState<Boolean?> = rememberPreferenceState(SettingsKeys.KEY_FORCE_DARK_MODE, null)
Last line there gives the exception in example stack trace 1 above.
Code example 2:
@Composable
fun AppSettingsApp() {
TravelitoTheme {
ProvidePreferenceLocals(
theme = preferenceTheme(categoryColor = MaterialTheme.colorScheme.primary)
) {
AppSettingsScreen()
}
}
}
@Composable
fun AppSettingsScreen() {
Scaffold(...) {
LazyColumn(modifier = Modifier.fillMaxSize(), contentPadding = contentPadding) {
listPreference(
key = SettingsKeys.KEY_FORCE_DARK_MODE,
icon = { Icon(ThemeIcons.DarkMode, "Theme") },
defaultValue = null,
values = listOf(true, false, null),//"Dark", "Light", "Follow System"),
title = { Text(text = "Theme") },
summary = { Text(text = stringResource(themeString(it as Boolean?))) },
valueToText = { AnnotatedString(context.getString(themeString(it as Boolean?))) }
)
..
Hey,
Thanks for this library, do you think you can make this library working for compose multiplatform, is that a thing that I can contribute on ?
Regards.
We have the following use case for SwitchPreference:
When the switch is clicked (value changes), we display a dialog explaining that the preference change will only take effect when the app exits and re-enters the foreground state.
If SwitchPreference supported "onCheckedChange", we could then support showing a Dialog to provide that information to the user.
Thanks!
How would we support different languages?
In the examples provided, titles and summaries are hard-coded. "That's ok" in the sense that before passing those strings to the composable, we can get the localized versions of the title and summary.
But there seems to be somekind of missing functionality if we want to display a language-localized version of a selected choice from a single-from-list, or multi-from-list preference. Indeed, if my choices are "1", "2", "3" I will want to persist them as such in SharedPreferences, but in terms of display, I could want them as words in english ("one", "two", "three") or in french ("un", "deux", "trois"), etc. There seems to be something missing to let the library show the localized versions of the single-or-multi choices.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.