如何在Jetpack Compose中设置Datastore初始状态为false?
问题原因及解决方案
你的问题出在DataStoreUtil中对Flow的映射逻辑里:
val getForceDarkTheme: Flow<Boolean> = context.dataStore.data .map { preferences -> preferences[FORCE_DARK_THEME] ?: true }
这里当Datastore中不存在FORCE_DARK_THEME这个key时,你设置的默认值是true,所以Flow会直接发射true。而collectAsState(false)里的false只是Flow还未发射任何值时的临时初始值,一旦Flow发射了数据(这里就是true),就会覆盖这个临时值,所以你看到的始终是true。
要把初始状态设为false,只需要把映射逻辑里的默认值改成false即可:
修改后的DataStoreUtil代码:
class DataStoreUtil(private val context: Context) { companion object { private val Context.dataStore: DataStore<androidx.datastore.preferences.core.Preferences> by preferencesDataStore("settings") val FORCE_DARK_THEME = booleanPreferencesKey("force_dark_theme") } val getForceDarkTheme: Flow<Boolean> = context.dataStore.data .map { preferences -> preferences[FORCE_DARK_THEME] ?: false // 这里改成false } suspend fun saveForceDarkTheme(value: Boolean) { context.dataStore.edit { preferences -> preferences[FORCE_DARK_THEME] = value } } }
另外,建议在Composable中使用remember缓存DataStoreUtil实例,避免每次重组都创建新对象:
@Composable fun MySwitch() { val scope = rememberCoroutineScope() val dataStore = remember { DataStoreUtil(LocalContext.current) } // 添加remember val switchState by dataStore.getForceDarkTheme.collectAsState(false) Switch( checked = switchState, onCheckedChange = { scope.launch{ dataStore.saveForceDarkTheme(it) } } ) Text( text = if(switchState) "foo" else "bar", ) }
这样修改后,当Datastore中没有保存过主题设置时,就会默认使用false作为初始值,符合你的需求。
内容的提问来源于stack exchange,提问作者Jorpy
相关产品推荐
相关产品推荐

