Setting Preference Summary

Noha Samir
3 min readOct 24, 2020

https://developer.android.com/guide/topics/ui/settings

1) Build a simple settings screen using the AndroidX Preference Library

2) A settings screen contains a Preference hierarchy. You can define this hierarchy as an XML resource, or you can build a hierarchy in code.

3) The root tag must be a <PreferenceScreen>, and the XML resource must be placed in the res/xml/ directory.

4) Create a hierarchy as an XML

<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">

<PreferenceCategory app:title="@string/messages_header">

<EditTextPreference
app:key="signature"
app:title="@string/signature_title"
app:useSimpleSummaryProvider="true" />

<ListPreference
app:defaultValue="reply"
app:entries="@array/reply_entries"
app:entryValues="@array/reply_values"
app:key="reply"
app:title="@string/reply_title"
app:useSimpleSummaryProvider="true" />

</PreferenceCategory>

<PreferenceCategory app:title="@string/sync_header">

<SwitchPreferenceCompat
app:key="sync"
app:title="@string/sync_title" />

<SwitchPreferenceCompat
app:dependency="sync"
app:key="attachment"
app:summaryOff="@string/attachment_summary_off"
app:summaryOn="@string/attachment_summary_on"
app:title="@string/attachment_title" />

</PreferenceCategory>

</PreferenceScreen>

To discover more components

https://developer.android.com/guide/topics/ui/settings/components-and-attributes

5) Inflate the hierarchy

class MySettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey)
}
}

6) Split your hierarchy into multiple screens

<PreferenceScreen
xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference
app:title="@string/basic_preferences"
app:summary="Sample preferences using basic attributes"
app:fragment="com.example.SyncFragment"/>
//---

Activity

class MyActivity : AppCompatActivity(),
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {

...

override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
// Instantiate the new Fragment
val args = pref.extras
val fragment = supportFragmentManager.fragmentFactory.instantiate(
classLoader,
pref.fragment)
fragment.arguments = args
fragment.setTargetFragment(caller, 0)
// Replace the existing Fragment with the new Fragment
supportFragmentManager.beginTransaction()
.replace(R.id.settings_container, fragment)
.addToBackStack(null)
.commit()
return true
}
}

7) Finding Preferences

val signaturePreference: EditTextPreference? = findPreference("key")signaturePreference?.setOnPreferenceChangeListener { preference, newValue ->
Toast.makeText(context, newValue.toString(), Toast.LENGTH_LONG).show()
true
}

8) Use a SimpleSummaryProvider to automatically display the saved Preference value as the summary

app:useSimpleSummaryProvider="true"

code

editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()

Use a custom SummaryProvider

countingPreference?.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
val text = preference.text
if (TextUtils.isEmpty(text)) {
"Not set"
} else {
"Length of saved value: " + text.length
}
}

9) Within an EditTextPreference dialog, you can customize text field behavior by attaching an OnBindEditTextListener . This listener is invoked when the dialog is shown to the user.

numberPreference?.setOnBindEditTextListener { editText ->
editText.inputType = InputType.TYPE_CLASS_NUMBER
}

10) A Preference can have a specific action when tapped

  • set an Intent on a Preference to launch a new Fragment, Activity . you can use an intent tag with Preference, SwitchPreferenceCompat, …etc
<intent 
android:targetPackage="com.example"
android:targetClass="com.example.ExampleActivity">
<extra
android:name="example_key"
android:value="example_value"/>
</intent>
onClickPreference.setOnPreferenceClickListener({
// do something
true
})

11) To retrieve the SharedPreferences object that is being used, call PreferenceManager.getDefaultSharedPreferences()

val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)
val name = sharedPreferences.getString("signature", "")

12) To listen for changes to Preference values, you can choose between two interfaces:

val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)sharedPreferences.registerOnSharedPreferenceChangeListener { sharedPreferences: SharedPreferences, key: String ->

}

Using a custom Data Store

13) you can also use a custom data store. A custom data store can be useful if your application persists values to a database or if values are device-specific

class DataStore : PreferenceDataStore() {
override fun putString(key: String, value: String?) {
// Save the value somewhere (Database / Server)
}

override fun getString(key: String, defValue: String?): String? {
// Retrieve the value
}
}

14) After you have implemented your data store, you must set the new data store in onCreatePreferences() so that Preference objects persist values with the data store instead of using the default SharedPreferences

val preference: Preference? = findPreference("key")
preference?.preferenceDataStore = dataStore

15) To enable a custom data store for an entire hierarchy, call setPreferenceDataStore() on the PreferenceManager

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

--

--