Search code examples
androidandroid-layoutandroid-preferences

Android findPreference() broken


I have the following preference layout:

xml/preferences.xml:

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

    <!-- Populate with paid preferences -->
    <PreferenceCategory android:title="Advanced" android:key="cat_pref_mods">

    </PreferenceCategory>

    <!-- Populate with debugging preferences -->
    <PreferenceCategory android:title="Dbg." android:key="cat_pref_dbg">

    </PreferenceCategory>

</PreferenceScreen>

The first category (with key "cat_pref_mods") get populated as expected by the following code:

PreferenceCategory  mPreferenceCategory = (PreferenceCategory) findPreference("cat_pref_mods");
PreferenceScreen parentScreen = (PreferenceScreen) findPreference("screen_pref");
// Add category now
parentScreen.addPreference(mPreferenceCategory);

However, when populating the second category similarly:

PreferenceCategory  mPreferenceCategory = (PreferenceCategory) findPreference("cat_pref_dbg");
PreferenceScreen parentScreen = (PreferenceScreen) findPreference("screen_pref");
// Add category now
parentScreen.addPreference(mPreferenceCategory);

The two category headers defined in preferences.xml, appear immediately one under each other and the actual preferences are concatenated afterwards.

Why doesn't category with key "cat_pref_mods" along with its entries appear entirely before category "cat_pref_dbg"?

While debugging the parent screen seems to be empty (""), even though is previously initialized:

addPreferencesFromResource(R.xml.preferences);

If only one category is created, the items appear as expected. When creating two, the category headers are placed immediately one under another, but the entries appear as expected afterwards.


Solution

  • It turns out that the categories, as well as the preferences have to be added in sequence (programmatically, as objects), something along the lines of:

    private void addPreferences() {
        addPreferencesFromResource(R.xml.preferences);
    
        PreferenceScreen parentScreen = (PreferenceScreen) findPreference(KEY_PREF_SCREEN);
    
        PreferenceCategory catOne= new PreferenceCategory(this);
        catOne.setTitle("Cat. #1");
        parentScreen.addPreference(catOne);
    
        addPreferencesFromResource(R.xml.preference_one);
    
        PreferenceCategory catTwo = new PreferenceCategory(this);
        catTwo .setTitle("Cat. #2");
        parentScreen.addPreference(catTwo);
    
        addPreferencesFromResource(R.xml.preference_two);
    }