【问题标题】:Type mismatch when changing Theme from options menu从选项菜单更改主题时类型不匹配
【发布时间】:2020-03-14 13:23:43
【问题描述】:

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

java.lang.Boolean 不能转换为 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
        )
}

【问题讨论】:

    标签: android kotlin android-theme android-preferences android-optionsmenu


    【解决方案1】:

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

    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
        )
    

    }

    【讨论】:

      【解决方案2】:

      我没有看到任何写入布尔值到 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)
      }
      

      您必须检查您的应用,并确保读取/写入布尔值的任何内容和读取/写入 int 的任何内容都使用不同的键。

      【讨论】:

      • 我认为我不应该使用private val prefTheme = "pref"。有没有办法使用选项菜单项单击事件来检查当前主题,然后切换到不同的主题(如果需要)并使用淡入淡出过渡重新启动 Activity?即startActivity( Intent(this, MainActivity::class.java) ) overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 实时?阅读preference_DarkTheme 首选项很好,因为我知道它会改变整个应用程序的首选项。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      • 1970-01-01
      • 2018-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-07
      相关资源
      最近更新 更多