如何在应用程序重新启动时阻止重置首选项数据存储中保存的值?

问题描述 投票:0回答:1

每当我重新启动应用程序时,首选项数据存储中保存的值都会重置。

特别是,我试图保存用户是否选择浅色模式或深色模式作为他们喜欢的背景主题。但是,当应用程序重新启动时,它不会保留。

我使用布尔值来确定背景主题,然后使用首选项数据存储区保存它。

这是保存该值的数据存储类。它称为“主题数据存储”

import android.content.Context
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

private val Context.dataStore by preferencesDataStore("ThemeDatastore")

class ThemeDatastore(private val context: Context) {`

Here is the key that holds the boolean that determines if the background theme is light or dark

`val themeKey = booleanPreferencesKey("Theme")

这是加载首选背景主题的函数。它采用布尔首选项键作为参数。

fun loadTheme(key: Preferences.Key<Boolean>): Flow<Boolean> = context.dataStore.data.map { preferences ->
        preferences[key] ?: false
    }

这里是保存首选背景主题的功能。它需要一个布尔首选项键和一个布尔变量作为参数。

suspend fun saveTheme(key: Preferences.Key<Boolean>, data: Boolean) {
        context.dataStore.edit { preferences ->
            preferences[key] = data
        }
    }

这是主活动中的代码

这是“ThemeDatastore”的实例。它在上下文参数字段中具有当前本地上下文。

val themeDatastore = ThemeDatastore(LocalContext.current)

这是检索首选背景主题的变量。它最初设置为 false。

val savedTheme = themeDatastore.loadTheme(key = themeDatastore.themeKey).collectAsState(initial = false)

这里是决定背景主题的布尔变量。如果为 false,则亮模式处于活动状态;如果为 true,则处于暗模式状态。它最初设置为 false。

var isDarkModeActive by remember { mutableStateOf(false) }

这是从“ThemeDatastore”调用函数来保存首选背景主题的函数。

fun saveTheme(){
                CoroutineScope(Dispatchers.IO).launch {
                    themeDatastore.saveTheme(themeDatastore.themeKey, isDarkModeActive)
                }
            }

这是应用程序布局。是一个占据整个屏幕的框。如果“isDarkModeActive”和“saveTheme.value”都等于 true,则背景颜色动画为深灰色。

Box(
                contentAlignment = Alignment.Center,
                modifier = Modifier
                    .background(
                        color = animateColorAsState(
                            targetValue = if (isDarkModeActive && savedTheme.value)
                                Color.DarkGray else Color.White
                        ).value
                    )
                    .fillMaxSize()
            ){

屏幕中央有一个按钮。当按下按钮时,“isDarkModeActive”在 true 和 false 之间切换,并触发 saveTheme 函数。

Button(onClick = {
                    isDarkModeActive = !isDarkModeActive
                    saveTheme() }) {
                    Text(text = "Toggle Theme")

                }

我尝试将“savedTheme”变量的初始值设置为true。没成功。

我不知道下一步该尝试什么。谢谢。

android-jetpack-compose boolean preferences android-jetpack-datastore
1个回答
0
投票

DataStore 工作得很好,只是在加载可组合项时将深色模式显式设置为 false:

var isDarkModeActive by remember { mutableStateOf(false) }

DataStore 的值并不重要,当您重新启动应用程序时,

isDarkModeActive
将始终为 false。

对于任何给定的数据,您应该只有单一的事实来源。在这种情况下,这意味着您应该删除指示深色模式是否打开的两个值之一:

val themeDatastore = ThemeDatastore(LocalContext.current)
val isDarkModeActive by themeDatastore.loadTheme(key = themeDatastore.themeKey)
    .collectAsStateWithLifecycle(false)
val scope = rememberCoroutineScope()

Box(
    contentAlignment = Alignment.Center,
    modifier = Modifier
        .background(
            color = animateColorAsState(
                targetValue = if (isDarkModeActive)
                    Color.DarkGray else Color.White,
            ).value,
        )
        .fillMaxSize(),
) {
    Button(onClick = {
        scope.launch {
            themeDatastore.saveTheme(themeDatastore.themeKey, !isDarkModeActive)
        }
    }) {
        Text(text = "Toggle Theme")
    }
}

虽然没有必要解决这个问题,但我做了两个额外的更改:

  1. 我将 gradle 依赖项
    collectAsState
    中的
    collectAsStateWithLifecycle
    替换为
    androidx.lifecycle:lifecycle-runtime-compose
    ,以便在生命周期发生变化时节省资源。
  2. 我删除了创建非托管
    saveTheme
    的函数
    CoroutineScope
    。相反,您应该使用
    rememberCoroutineScope()
    检索托管范围。

现在应该可以按预期工作了。

最后一件事:传递给

saveTheme
的密钥应该在该函数中硬编码,而不是作为参数传递。除了
themeDatastore.themeKey
之外,您永远不会想要传递其他东西。

© www.soinside.com 2019 - 2024. All rights reserved.