屏幕以浅色或深色模式启动,并根据用户设置更改为深色或浅色模式

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

我正在使用数据存储为我的应用程序制作浅色模式和深色模式。

当我打开应用程序时,根据设备是否处于深色模式,应用程序以深色模式启动,然后突然切换到浅色模式(如果用户已将应用程序设置为浅色模式)。

如果设备未处于深色模式,然后应用程序以浅色模式启动,然后突然切换到深色模式(如果用户已将应用程序设置为深色模式),也会发生这种情况。

HomeMenuActivity 类

class HomeMenuActivity : AppCompatActivity() {

    //UI elements
    private lateinit var settingsButton: ConstraintLayout

    //primitive values
    private var booleanNightMode: Boolean = false

    //instantiations
    private lateinit var appSettingsDarkModeViewModel: AppSettingsDarkModeViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        installSplashScreen()
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home_menu)
        setupUI()
    }

    private fun setupUI(){

        settingsButton = findViewById(R.id.button_settings)

        loadDataStoreValues()

    }

    private fun loadDataStoreValues(){

        appSettingsDarkModeViewModel = ViewModelProvider(this)[AppSettingsDarkModeViewModel::class.java]

        Handler(Looper.getMainLooper()).postDelayed({

            appSettingsDarkModeViewModel.getTheme.observe(this){ pref ->
                booleanNightMode = pref
            }
            settings()
        },0)

    }

    private fun settings(){

        Handler(Looper.getMainLooper()).postDelayed({
            if(booleanNightMode){
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
            }
            else{
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            }
            setupButtons()
        },50)
    }

    private fun setupButtons(){

        settingsButton.setOnClickListener{
            val nextPage = Intent(this, SettingsMenuActivity::class.java)
            startActivity(nextPage)
            finish()
        }
    }
}

AppSettingsDarkModeDataStore 类

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

class AppSettingsDarkModeDataStore(context: Context) {

    private val dataStore = context.dataStore

    companion object {
        val darkModeKey = booleanPreferencesKey("DARK_MODE_KEY")
    }

    suspend fun setTheme(isDarkMode : Boolean){
        dataStore.edit { pref ->
            pref[darkModeKey] = isDarkMode
        }
    }

    val getTheme : Flow<Boolean> = dataStore.data
            .catch { exception ->
                if(exception is IOException) {
                    emit(emptyPreferences())
                }
                else {
                    throw exception
                }
            }
            .map { pref ->
                val uiMode = pref[darkModeKey] ?: false
                uiMode
            }
    }

AppSettingsDarkModeViewModel 类

class AppSettingsDarkModeViewModel(application: Application): AndroidViewModel(application) {

    private val repository = AppSettingsDarkModeDataStore(application)

    val getTheme = repository.getTheme.asLiveData()

    fun setTheme(isDarkMode : Boolean) = viewModelScope.launch {
        repository.setTheme(isDarkMode)
    }
}

我还尝试在视图模型类(以及主菜单活动)中使用 runBlocking,但它所做的只是在我转到下一个或上一个屏幕时导致屏幕闪烁为白色或黑色。我什至尝试将asLiveData 括号内的“Dispatchers.IO”,但这没有什么区别。

kotlin darkmode android-jetpack-datastore
1个回答
0
投票

我没有使用数据存储,也没有使用 XML,但在我的撰写应用程序中,我遇到了这样的问题,我通过使用共享首选项解决了它,并且所选主题是基于 Int 的(0 - 浅色,1 - 深色,3 - 系统)。

制作一个可变状态流来存储主题值 在应用程序开始时从共享首选项中检索主题并更新状态流 当您更改应用程序的主题时,您会更新状态流,还会使用新的主题值更新共享首选项

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