使用 PreferencesDataStore 将主题设置为 activity

SetTheme to an activity with PreferencesDataStore

我已将我的应用程序从使用 SharedPreferences 切换到 PreferencesDataStore。我还在我的应用程序中实现了暗模式和几个主题。对于主题,我基本上依赖于每个 activity 这段代码:

    val themePreferences = getSharedPreferences("THEME_PREFERENCES", MODE_PRIVATE)
    val settingsPreferences = getSharedPreferences("SETTINGS_PREFERENCES", MODE_PRIVATE)
    darkMode = settingsPreferences.getBoolean("darkMode", false)

    setTheme(when (darkMode) {
        true -> themePreferences.getInt("themeDark", R.style.AppThemeDark)
        false -> themePreferences.getInt("themeLight", R.style.AppThemeLight)
    })

选定的主题被存储为一个整数,每一个用于浅色模式和深色模式。现在,我也想采用我的这部分代码。我像这样从我的数据存储库中获取我的 darkMode 布尔值:

viewModel.storedDarkMode.observe(this) { darkMode = it }

如果我在 LiveData 对象的 observe(this) { ... } 内部工作,它将无法工作。

现在,如何将上面显示的代码片段更改为 PreferencesDataStore?或者它实际上更好吗?制作一个单独的 class 以便从那里观察值?如果是的话,那样的东西怎么可能看起来像?或者您是否知道 Android 体系结构之后的一些很好的示例代码,包括自定义主题和我可以查看的黑暗模式?

我仍在学习很多东西,非常感谢任何有助于更好地理解这一点的帮助!

此致,马库斯

编辑:

runBlocking {
        val darkMode = viewModel.darkModeFlow.first()
        setTheme(when (darkMode) {
            true -> viewModel.themeDarkFlow.first()
            false -> viewModel.themeLightFlow.first()
        })
    }

我不知道这是否是最佳实践,但我使用 runBlockingdataStore 获取主题数据。始终建议我们永远不要在生产代码中使用 runBlocking

val preferences = runBlocking {
    mainActivityViewModel.preferencesFlow.first()
}
setAppTheme(preferences.currentTheme)
binding = ActivityMainBinding.inflate(layoutInflater)

setAppTheme方法中

private fun setAppTheme(theme: Boolean) {
        mainActivityViewModel.darkMode = theme
        //set your theme here
    }

现在观察 preferencesFlow 主题值的任何变化,如果主题发生变化则 recreate()

mainActivityViewModel.preferencesLiveData.observe(this) {
        if (it.currentTheme != mainActivityViewModel.selectedTheme) {
            recreate()
        }
    }

因为我们无法在未获取主题的情况下加载 UI。使用 runBlocking.

似乎是正确的