androidandroid-preferencesscreen-orientationpreferencefragmentpreferencescreen

PreferenceScreen in PreferenceFragment closing on ScreenOrientation change


I got some nested PreferenceScreen in my PreferenceActivity, and under them a series of CheckBoxPreference.

Everything is working well but, whenever the device is rotated, the PreferenceActivity returns to the main PreferenceScreen, disregarding what nested preference screen the user was in.

This is exactly like in these previous SO questions, where the solution was to add a key to the PreferenceScreen:

  1. When my PreferenceActivity rotates, it does not remember which PreferenceScreen was open

  2. How to prevent quitting from inner preference screen when there's a configuration change

  3. Nested Preference Screen closes on Screenorientation change in Android

I've added keys to all my PreferenceScreen and the solution works, as long as I use the deprecated way:

public class Settings extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.prefs);
    }
}

The problem is I'm using a PreferenceFragment, like in this SO answer (and also here).

The code:

public class Settings extends PreferenceActivity {

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    getFragmentManager().
            beginTransaction().
            replace(android.R.id.content, new MyPreferenceFragment()).
            commit();
}

    public static class MyPreferenceFragment extends PreferenceFragment
    {
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.prefs);
        }
    }
}

So, how to keep inner PreferenceScreen open after screen orientation changes, if possible with the current code?

I see that for Preferences Google now recommends AppCompatActivity and PreferenceFragmentCompat, but I would prefer to not use any libraries, not even Google's, specially for only such a small detail.


Solution

  • I'm quite surprised this little problem managed to generate three SO questions while Android was under API 11, and none - that I can find at least - between API 11 and API 28, when PreferenceFragment was deprecated.

    Anyways, I found the solution here in SO as well, in an answer to Android- deprecated method warning regarding PreferenceActivity.

    The key is to check if (savedInstanceState == null) before adding the PreferenceFragment, like this:

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null)
            getFragmentManager().
                    beginTransaction().
                    replace(android.R.id.content, new MyPreferenceFragment()).
                    commit();
    }
    

    Now the nested PreferenceScreen remains open when screen orientation changes, as long as it has an android:key value set in, of course.