从选项菜单更改主题时类型不匹配

Type mismatch when changing Theme from options menu

我试图在运行时通过单击选项菜单项更改应用程序主题,但它不起作用,而且我的应用程序不断崩溃。解决此错误的正确方法是什么? Android Studio 不提供任何建议,更不用说有用的建议了。

java.lang.Boolean cannot be cast to java.lang.Integer

class MainActivity : AppCompatActivity() {
    private val prefTheme = "preference_DarkTheme"

    override fun onCreate(savedInstanceState: Bundle?) {
        useDarkTheme = shouldUseDarkTheme()
        setTheme(
            if (useDarkTheme) R.style.DarkTheme
            else R.style.LightTheme
        )

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onStart() {
        super.onStart()

        if (useDarkTheme != shouldUseDarkTheme()) recreate()
    }


    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }


    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_changeTheme -> {
                switchTheme()
                restartActivity()

                Toast.makeText(this, "Test", Toast.LENGTH_SHORT).show()
                true
            }
            else -> { super.onOptionsItemSelected(item) }
        }
    }

    private fun getSavedTheme(): Int {
        return PreferenceManager.getDefaultSharedPreferences(this)
            .getInt(prefTheme, R.style.LightTheme)
    }

    private fun switchTheme() {
        val newTheme: Int =
            if (getSavedTheme() == R.style.LightTheme) R.style.DarkTheme else R.style.LightTheme
        PreferenceManager.getDefaultSharedPreferences(this)
            .edit()
            .putInt(prefTheme, newTheme)
            .apply()
    }

    private fun restartActivity() {
        startActivity(
            Intent(this, MainActivity::class.java)
        )
        overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
        finish()
    }

    private fun shouldUseDarkTheme(): Boolean =
        PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
            "preference_DarkTheme",
            false
        )
}

我没有看到任何代码写入 SharedPreferences 的布尔值,但您确实有读取 布尔值的代码:

private fun shouldUseDarkTheme(): Boolean =
    PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
        "preference_DarkTheme",
        false
    )

这让我假设,在过去的某个时候,您有使用该键写入布尔值的代码。

现在您有读取 Int 值的代码,但它使用与之前的布尔代码相同的键:

private val prefTheme = "preference_DarkTheme"

private fun getSavedTheme(): Int {
    return PreferenceManager.getDefaultSharedPreferences(this)
        .getInt(prefTheme, R.style.LightTheme)
}

您必须检查您的应用程序并确保 reads/writes 布尔值和 reads/writes 整数的任何内容使用不同的键。

您在 setNewTheme() 中将 prefTheme 的值设置为 Int,并在 shouldUseDarkTheme() 中将其设置为布尔值。您的问题的解决方案是存储一个 int 用于样式,另一个 boolean 用于检查是否应用深色主题。

class MainActivity : AppCompatActivity() {
private val prefTheme = "preference_DarkTheme"
private val applydarktheme = "applydarktheme"

override fun onCreate(savedInstanceState: Bundle?) {
    useDarkTheme = shouldUseDarkTheme()
    setTheme(
        if (useDarkTheme) R.style.DarkTheme
        else R.style.LightTheme
    )

    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
}

override fun onStart() {
    super.onStart()

    if (useDarkTheme != shouldUseDarkTheme()) recreate()
}


override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_main, menu)
    return true
}


override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.action_changeTheme -> {
            switchTheme()
            restartActivity()

            Toast.makeText(this, "Test", Toast.LENGTH_SHORT).show()
            true
        }
        else -> { super.onOptionsItemSelected(item) }
    }
}

private fun getSavedTheme(): Int {
    return PreferenceManager.getDefaultSharedPreferences(this)
        .getInt(prefTheme, R.style.LightTheme)
}

private fun switchTheme() {
    val newTheme: Int =
        if (getSavedTheme() == R.style.LightTheme){ R.style.DarkTheme} else{ R.style.LightTheme}

    if (newTheme== R.style.DarkTheme){
        PreferenceManager.getDefaultSharedPreferences(this)
            .edit()
            .putBoolean(applydarktheme, true)
            .apply()
    }else{
        PreferenceManager.getDefaultSharedPreferences(this)
            .edit()
            .putBoolean(applydarktheme, false)
            .apply()
    }


    PreferenceManager.getDefaultSharedPreferences(this)
        .edit()
        .putInt(prefTheme, newTheme)
        .apply()
}

private fun restartActivity() {
    startActivity(
        Intent(this, MainActivity::class.java)
    )
    overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
    finish()
}

private fun shouldUseDarkTheme(): Boolean =
    PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
        applydarktheme,
        false
    )

}