After declaring a CheckboxPreference
in my activity for my app's settings, a warning appears for as
in the line 'val mCheckBoxPreference = findPreference("preference_a") as CheckBoxPreference
'. What should be done so that the cast does succeed?
This cast can never succeed
app_preferences.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="preference_a"
android:defaultValue="false"
android:title="Preference A"/>
</PreferenceScreen>
fragment class
import android.content.Context
import android.os.Bundle
import android.preference.CheckBoxPreference
import android.preference.Preference
import android.support.v7.preference.PreferenceFragmentCompat
import android.util.Log
class MySettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.app_preferences)
val mCheckBoxPreference = findPreference("preference_a") as CheckBoxPreference
mCheckBoxPreference.onPreferenceChangeListener = this
}
// declaring PreferenceXchangeListener
private var mPreferenceXchangeListener: PreferenceXchangeListener? = null
// declaring PreferenceXchangeListener in order to communicate with Activities
interface PreferenceXchangeListener {
fun onXchange(value:Boolean)
}
override fun onAttach(context: Context) {
super.onAttach(context)
// on attach - assign parent Activity as PreferenceXchangeListener
try
{
mPreferenceXchangeListener = context as MySettingsFragment.PreferenceXchangeListener
}
catch (e:ClassCastException) {
Log.e(TAG, "onAttach::::: PreferenceXchangeListener must be set in parent Activity")
}
}
override fun onPreferenceChange(preference: Preference, newValue:Any):Boolean {
val preferenceKey = preference.key
if (preferenceKey == "preference_a")
{
(preference as CheckBoxPreference).isChecked = newValue as Boolean
// executing parent Activity's callback with the new value
mPreferenceXchangeListener!!.onXchange(newValue)
return true
}
return false
}
companion object {
private val TAG = MySettingsFragment::class.java.simpleName
}
}
activity class
class MySettingsActivity : AppCompatActivity(), MySettingsFragment.PreferenceXchangeListener {
private var mCurrentValue: Boolean? = null
override fun onCreate(savedInstanceState: Bundle?) {
val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
mCurrentValue = mSharedPreferences.getBoolean("preference_a", false)
if (mCurrentValue as Boolean)
{
setTheme(R.style.MyDarkAppCompatTheme)
}
else
{
setTheme(R.style.MyLightAppCompatTheme)
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_mysettings)
val settingsFragment = MySettingsFragment()
supportFragmentManager
.beginTransaction()
.replace(R.id.settings_container, settingsFragment)
.commit()
val myActionBar = actionBar
if (myActionBar != null)
{
myActionBar.setTitle(R.string.settings)
myActionBar.setBackgroundDrawable(ColorDrawable(Color.BLACK))
}
}
override fun onXchange(value:Boolean) {
if (value !== mCurrentValue)
{
mCurrentValue = value
recreate()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
val intent = parentActivityIntent
intent?.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
onBackPressed()
return true
}
else ->
return super.onOptionsItemSelected(item)
}
}
companion object {
private val TAG = MySettingsActivity::class.java.simpleName
}
}
TL;DR You have to change the import to android.support.v7.preference.CheckBoxPreference
.
There are two versions of CheckBoxPreference
:
android.preference.CheckBoxPreference
, which was added in API level 1 and has android.preference.Preference
as ancestor classandroid.support.v7.preference.CheckBoxPreference
which belongs to the support library and has android.support.v7.preference.Preference
as ancestor classYour Fragment
extends from PreferenceFragmentCompat
, so findPreference()
will return a android.support.v7.preference.Preference
. Since you can't cast support Preference
classes to their non support equivalents, Android Studio is showing the error message "This cast can never succeed" when you attempt to cast to the non support CheckBoxPreference
.