Search code examples
androidkotlinandroid-preferencesandroidxpreferencefragment

Why does the nested PreferenceScreen not open when using AndroidX?


I am using AndroidX's Preference library to manage my app's settings. My SettingsFragment derives from PreferenceFragmentCompat and loads the following layout:

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

    <androidx.preference.PreferenceScreen
        android:key="screen_backup_key"
        android:title="@string/local_database">

        <androidx.preference.Preference
            android:key="button_save_key"
            android:title="@string/export" />

        <androidx.preference.Preference
            android:key="button_load_key"
            android:title="@string/_import" />

    </androidx.preference.PreferenceScreen>

    <androidx.preference.Preference
            android:key="screen_about"
            android:title="@string/about" />

</androidx.preference.PreferenceScreen>

The layout is displayed correctly, but when I click on the nested PreferenceScreen entry nothing happens. It worked before with the PreferenceScreen from the Support Library, which is now deprecated.

I would expect to see the contents to this nested PreferenceScreen. What am I doing wrong?


Solution

  • It is not supported anymore in AndroidX's Preference Library.

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

    You need a separate PreferenceFragmentCompat for each separate screen.

    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.

    You do it like this:

    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"
        .../>
    

    Here is the source for further reading.