Android How to Implement ListPreference (Kotlin)

August 20, 2018

Refer to tutorials on how to implement settings using PreferenceFragment or PreferenceFragmentCompat.

Edit R.xml.pref* files with PreferenceScreen.

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">

    <ListPreference
        android:key="@string/pref_key_auto_lock_duration"
        android:title="Auto Lock"
        android:summary="Always prompt password login when the app is inactive for a while"
        android:entries="@array/pref_auto_lock_labels"
        android:entryValues="@array/pref_auto_lock_values"
        android:defaultValue="0"
        />

</PreferenceScreen>    

Edit res/values/arrays.xml.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="pref_auto_lock_labels">
        <item>Disabled</item>
        <item>30 seconds</item>
        <item>1 minute</item>
        <item>5 minutes</item>
        <item>15 minutes</item>
    </string-array>

    <string-array name="pref_auto_lock_values">
        <item>0</item>
        <item>30</item>
        <item>60</item>
        <item>300</item>
        <item>900</item>
    </string-array>
</resources>

The following code initialize title based on current preference, and change the title when preference value changed.

class SettingsFragment: PreferenceFragmentCompat() {
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        if (context != null) {
            activityContext = context as Context
        }

        val autoLocakDurationPreference = findPreference(getString(R.string.pref_key_auto_lock_duration)) as ListPreference
        autoLocakDurationPreference.title = "Auto Lock (${ autoLocakDurationPreference.entry})"
        autoLocakDurationPreference.setOnPreferenceChangeListener { preference, newValue ->
            if (preference is ListPreference) {
                // preference.title = "Auto Lock ($newValue)"
                val index = preference.findIndexOfValue(newValue.toString())
                val entry = preference.entries.get(index)
                preference.title = "Auto Lock ($entry)"
            }

            true
        }
    }
}  

Load fragment into activity.

class SettingsActivity : LuaActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_settings)

        supportFragmentManager.beginTransaction()
                .replace(R.id.content, SettingsFragment())
                .commit()
    }
}

NOTE: Refer to PreferenceFragmentCompat tutorial for more detail.

To read this preference value in other activities.

val sharedPref = PreferenceManager.getDefaultSharedPreferences(activity?.applicationContext)
val value = sharedPref.getString(activity?.getString(R.string.pref_key_auto_lock_duration), "0").toLong()
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.