martmists
06/29/2024, 10:50 AMval theme by settings.bound<AppTheme>(default=MaterialAppTheme(isSystemInDarkTheme()))
but if I change this value elsewhere in the code, I need to tell this part to reload and trigger a recomposition. How would I do this? I tried reading the source for MutableState but didn't quite understand how that triggered recompositions.Meet
06/29/2024, 12:04 PMin viewmodel
private val _isDarkModeEnabled = MutableStateFlow(false)
val isDarkModeEnabled = _isDarkModeEnabled.asStateFlow()
in compose file
val isDarkModeEnabled by settingViewModel.isDarkModeEnabled.collectAsState(isSystemInDarkTheme())
martmists
07/01/2024, 12:31 PMsettingViewModel.isDarkModeEnabled
will trigger a recomposition?Meet
07/01/2024, 12:32 PMmartmists
07/01/2024, 12:34 PM@Suppress("UNCHECKED_CAST")
class BoundSetting<T>(private val settings: Settings, private val key: String?, private val default: T?, private val type: KType, private val serializer: KSerializer<T>) {
private val flow = MutableStateFlow(default)
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
@Suppress("IMPLICIT_CAST_TO_ANY")
val res = when (type) {
String::class -> settings.getStringOrNull(key ?: property.name)
Int::class -> settings.getIntOrNull(key ?: property.name)
Long::class -> settings.getLongOrNull(key ?: property.name)
Float::class -> settings.getFloatOrNull(key ?: property.name)
Double::class -> settings.getDoubleOrNull(key ?: property.name)
Boolean::class -> settings.getBooleanOrNull(key ?: property.name)
else -> settings.getStringOrNull(key ?: property.name)?.let { Json.decodeFromString(serializer, it) }
}
return (res ?: default) as T
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
flow.value = value
if (value == null) {
settings.remove(key ?: property.name)
return
}
when (type) {
String::class -> settings.putString(key ?: property.name, value as String)
Int::class -> settings.putInt(key ?: property.name, value as Int)
Long::class -> settings
Float::class -> settings
Double::class -> settings
Boolean::class -> settings
else -> settings.putString(key ?: property.name, Json.encodeToString(serializer, value))
}
}
@Composable
fun asComposeState() = flow.collectAsState(default)
companion object {
inline operator fun <reified T> invoke(settings: Settings, key: String?, default: T): BoundSetting<T> {
return BoundSetting(settings, key, default, typeOf<T>(), serializer())
}
inline operator fun <reified T> invoke(settings: Settings, key: String?): BoundSetting<T?> {
return BoundSetting(settings, key, null, typeOf<T>(), serializer())
}
}
}
Or would this give the wrong value if asComposeState
is called after setValue
?Meet
07/01/2024, 12:38 PMfun changeDarkMode(isEnabled: Boolean) = viewModelScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
appPreferencesImpl.changeDarkMode(isEnabled)
_isDarkModeEnabled.value = isEnabled
}
martmists
07/01/2024, 12:38 PMMeet
07/01/2024, 12:39 PMmartmists
07/01/2024, 12:40 PMmartmists
07/01/2024, 12:41 PMMeet
07/01/2024, 12:41 PMmartmists
07/01/2024, 12:42 PMMeet
07/01/2024, 12:44 PMMeet
07/01/2024, 12:45 PMmartmists
07/01/2024, 12:45 PMMeet
07/01/2024, 12:47 PM