[Java] Nesting PreferenceScreen breaks the outer layout

1 minute read

In the setting screen using PreferenceFragment, for example, if you try to easily create a Preference of multiple screens

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceScreen android:title="test1">
        <Preference android:title="test1-1">
        <Preference android:title="test1-2">
    </PreferenceScreen>
</PreferenceScreen>

You can create multiple screens by nesting with this, but in this case, the nested PreferenceScreen screen will not have the layout (ActionBar, buttombar, etc.) that you might have designed in the parent PreferenceScreen. So, I managed to change the Fragment by switching to another fragment by clicking the parent Preference element.

SettingActivity.java


public class SettingActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // activity_setting.xml is the layout xml that contains the fragment
        setContentView(R.layout.activity_setting);
        getFragmentManager().beginTransaction().replace(R.id.fragment_container,
                new UserPreferenceFragment()).commit();
    }
}

class UserPreferenceFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // preference_header.xml is the parent preference screen xml
        addPreferencesFromResource(R.xml.preference_header);
        Preference.OnPreferenceClickListener subpreference = new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                getPreferenceScreen().removeAll();
                switch(preference.getKey()) {
                    // preference_test1,2,3 are child preference screens
                    case "test1":
                        addPreferencesFromResource(R.xml.preference_test1); break;
                    case "test2":
                        addPreferencesFromResource(R.xml.preference_test2); break;
                    case "test3":
                        addPreferencesFromResource(R.xml.preference_test3); break;
                }
                return true;
            }
        };
        final Preference test1 = (Preference) findPreference("test1");
        final Preference test2 = (Preference) findPreference("tesst2");
        final Preference test3 = (Preference) findPreference("test3");
        test1.setOnPreferenceClickListener(subpreference);
        test2.setOnPreferenceClickListener(subpreference);
        test3.setOnPreferenceClickListener(subpreference);
    }
}

It’s really plain, but I struggled to make multiple setOnPreferenceClickListener as clean as possible. (Since it was too much to define and fit one by one)

reference:

Call INTENT from PREFERENCE ACTIVITY