Join us on the livestream at Android Dev Summit on 7-8 November 2018, starting at 10AM PDT!

Customize your settings   Part of Android Jetpack.

This topic describes how to customize Preferences in your hierarchy.

Finding Preferences

To access an individual Preference, such as when getting or setting a Preference value, use PreferenceFragmentCompat.findPreference(). This method searches the entire hierarchy for a Preference with the given key.

As an example, given an EditTextPreference with a key of "signature":

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

We can retrieve this Preference by using the following code:

Kotlin

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    val preference = findPreference("signature") as EditTextPreference
    // do something with this preference
}

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    EditTextPreference preference = (EditTextPreference) findPreference("signature");
    // do something with this preference
}

Control Preference visibility

You can control which Preferences are visible to the user when they navigate to a settings screen. For example, if a particular Preference is meaningful only when a corresponding feature is enabled, you might want to hide that Preference when the feature is disabled.

To show a Preference only when a condition is met, first set the Preference visibility to false in the XML, as shown in the example below:

<EditTextPreference
        app:key="signature"
        app:title="Your signature"
        app:isPreferenceVisible="false"/>

Next, in onCreatePreferences(), show the Preference when the corresponding condition is met:

Kotlin

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    if(/*some feature*/) {
        val preference = findPreference("signature")
        preference.isVisible = true
    }
}

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    if(/*some feature*/) {
        Preference editTextPreference = findPreference("signature");
        editTextPreference.setVisible(true);
    }
}

Dynamically update summaries

A Preference that persists data should display the current value in its summary to help the user better understand the current state of the Preference. For example, an EditTextPreference should show the currently saved text value, and a ListPreference should show the currently selected list entry. You might also have Preferences that need to update their summary based on internal or external app state—a Preference that displays a version number, for example. This can be done using a SummaryProvider.

Use a SimpleSummaryProvider

ListPreference and EditTextPreference. include simple SummaryProvider implementations that automatically display the saved Preference value as the summary. If no value has been saved, they display "Not set".

You can enable these implementations from XML by setting app:useSimpleSummaryProvider="true".

Alternatively, in code you can use ListPreference.SimpleSummaryProvider.getInstance() and EditTextPreference.SimpleSummaryProvider.getInstance() to get the simple SummaryProvider instance and then set it on the Preference, as shown in the following example:

Kotlin

listPreference.summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()

Java

listPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
editTextPreference.setSummaryProvider(EditTextPreference.SimpleSummaryProvider.getInstance());

Use a custom SummaryProvider

You can create your own SummaryProvider and override provideSummary() to customize the summary whenever it is requested by the Preference. For example, the EditTextPreference below displays the length of its saved value as the summary:

As an example, assume the following EditTextPreference:

<EditTextPreference
        app:key="counting"
        app:title="Counting preference"/>

In onCreatePreferences(), create a new SummaryProvider, and override provideSummary() to return the summary to be displayed:

Kotlin

val countingPreference = findPreference("counting") as EditTextPreference

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

Java

EditTextPreference countingPreference = (EditTextPreference) findPreference("counting");

countingPreference.setSummaryProvider(new SummaryProvider<EditTextPreference>() {
    @Override
    public CharSequence provideSummary(EditTextPreference preference) {
        String text = preference.getText();
        if (TextUtils.isEmpty(text)){
            return "Not set";
        }
        return "Length of saved value: " + text.length();
    }
});

The Preference summary now displays the length of the saved value or "Not set" when no saved value exists.

Preference actions

A Preference can have a specific action when tapped. For example, a Preference can act as a link to a separate part of your application. To add an action to a Preference, you can either set an Intent on the Preference directly, or you can set an OnPreferenceClickListener for more specific logic.

Set an Intent

You can set an Intent on a Preference to launch a new Fragment, Activity, or separate application whenever the Preference is tapped. This is the same as using Context.startActivity() with a given Intent.

You can set an Intent in XML using a nested <intent> tag. The example below defines an Intent that launches an Activity:

<Preference
        app:key=”activity”
        app:title="Launch activity">
    <intent
            android:targetPackage="com.example"
            android:targetClass="com.example.ExampleActivity"/>
</Preference>

Alternatively, you can use setIntent() directly on a Preference, as shown below:

Kotlin

val intent = Intent(context, ExampleActivity::class.java)
activityPreference.setIntent(intent)

Java

Intent intent = new Intent(getContext(), ExampleActivity.class);
activityPreference.setIntent(intent);

You can also include extras with an Intent via XML:

<Preference
        app:key=”activity”
        app:title="Launch activity">
    <intent
            android:targetPackage="com.example"
            android:targetClass="com.example.ExampleActivity">
        <extra
                android:name="example_key"
                android:value="example_value"/>
    </intent>
</Preference>

Here is an example of a Preference with an Intent that launches a web page:

<Preference
        app:key=”webpage”
        app:title="View webpage">
    <intent
            android:action="android.intent.action.VIEW"
            android:data="http://www.google.com" />
</Preference>

Kotlin

val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("http://www.google.com")
webpagePreference.setIntent(intent)

Java

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
webpagePreference.setIntent(intent);

OnPreferenceClickListener

You can set an OnPreferenceClickListener on a Preference, which adds a callback to onPreferenceClick() when the Preference is tapped. For example, you can use the listener to navigate to another Fragment or Activity if you have more complex logic for handling navigation.

To set an OnPreferenceClickListener, use code similar to the following:

Kotlin

onClickPreference.setOnPreferenceClickListener({
    // do something
    true
})

Java

onClickPreference.setOnPreferenceClickListener(preference -> {
    // do something
    return true;
});