Organize your settings   Part of Android Jetpack.

Large and complex settings screens can make it difficult for a user to find a specific setting they would like to change. The Preference Library offers the following ways to better organize your settings screens.

Preference categories

If you have several related Preferences on a single screen, you can group them with a PreferenceCategory. A PreferenceCategory displays a category title and visually separates the category.

To define a PreferenceCategory in XML, wrap the Preference tags with a PreferenceCategory, as shown below:

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

    <PreferenceCategory
        app:key="notifications_category"
        app:title="Notifications">

        <SwitchPreferenceCompat
            app:key="notifications"
            app:title="Enable message notifications"/>

    </PreferenceCategory>

    <PreferenceCategory
        app:key="help_category"
        app:title="Help">

        <Preference
            app:key="feedback"
            app:summary="Report technical issues or suggest new features"
            app:title="Send feedback"/>

    </PreferenceCategory>

</androidx.preference.PreferenceScreen>
Figure 1. Preferences within categories.

Split your hierarchy into multiple screens

If you have a large number of Preferences or distinct categories, you can display them on separate screens. Each screen should be a PreferenceFragmentCompat with its own separate hierarchy. Preferences on your initial screen can then link to subscreens that contain related Preferences.

Figure 2 shows a simple hierarchy that contains two categories: Messages and Sync.

Figure 2. A simple hierarchy with two categories.

Figure 3 shows the same set of Preferences split on multiple screens:

Figure 3. A hierarchy split into multiple screens.

To link screens with a Preference, you can declare an app:fragment in XML, or you can use Preference.setFragment(). Set the full package name of the PreferenceFragmentCompat that should be launched when the Preference is tapped, as shown below:

<Preference
        app:fragment="com.example.SyncFragment"
        .../>

When a user taps a Preference with an associated Fragment, the interface method PreferenceFragmentCompat.OnPreferenceStartFragmentCallback.onPreferenceStartFragment() is called. This method is where you should handle displaying the new screen and should be implemented in the surrounding Activity.

A typical implementation looks similar to the following:

Kotlin

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,
                args)
        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
    }
}

Java

public class MyActivity extends AppCompatActivity implements
        PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {

    ...

    @Override
    public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
        // Instantiate the new Fragment
        final Bundle args = pref.getExtras();
        final Fragment fragment = getSupportFragmentManager().getFragmentFactory().instantiate(
                getClassLoader(),
                pref.getFragment(),
                args);
        fragment.setArguments(args);
        fragment.setTargetFragment(caller, 0);
        // Replace the existing Fragment with the new Fragment
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.settings_container, fragment)
                .addToBackStack(null)
                .commit();
        return true;
    }
}

PreferenceScreens

Declaring nested hierarchies within the same XML resource using a nested <PreferenceScreen> is no longer supported. You should use nested Fragment objects instead.

Use separate Activities

Alternatively, if you need to heavily customize each screen, or if you want full Activity transitions between screens, you can use a separate Activity for each PreferenceFragmentCompat. By doing this, you can fully customize each Activity and its corresponding settings screen. For most applications, this is not recommended, and you should use Fragments as previously described.

For more information about launching Activities from a Preference, see Preference actions.