Removing children of (sub-) PreferenceScreen not possible after orientation change
<p>I have a <code>OnPreferenceClickListener</code> which should remove a specific <code>Preference</code> (with key <code>preference_to_remove</code>) from a <code>PreferenceScreen</code>.</p>

<p>The problem is that my solution works when <code>preference_to_remove</code> is not located inside a nested <code>PreferenceScreen</code> but does not work, when it is inside a nested screen AND the screen orientation changes. Before screen orientation changes, nested screens are working as expected, too.</p>

<p>The following code contains two version, one with a flat non-nested <code>PreferenceScreen</code> and the broken nested <code>PreferenceScreen</code>.</p>

<p>What is the reason that the nested version is not able to remove the <code>Preference</code> with key <code>preference_to_remove</code> after screen orientation changes? What would be a solution besides using only flat <code>PreferenceScreens</code> and <code>Intents</code> to start new <code>PreferenceScreens</code> as pseudo children?</p>

<p>PS: I am using <code>PreferenceActivity</code> for FroYo compatibility.</p>

<p><strong>How to reproduce with Test-App</strong></p>

<p>Open App → Click Flat-Button → Click <code>preference_to_click</code> which should remove <code>preference_to_remove</code>. → Orientation change → Click <code>preference_to_click</code> to remove <code>preference_to_remove</code> again. Preference removed? Success!</p>

<p>Open App → Click Subscreen-Button → Click Test → Now repeat the steps from the first test, but this time <code>preference_to_remove</code> will be not not removable after orientation changing.</p>

<p><a href="http://www.sendspace.com/file/0f69ma" rel="nofollow">Download App (Source)</a></p>

<p><strong>pref_flat.xml</strong></p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" &gt;

    &lt;Preference
        android:key="preference_to_click"
        android:persistent="false"
        android:title="preference_to_click" /&gt;
    &lt;Preference
        android:key="preference_to_remove"
        android:title="preference_to_remove" /&gt;

&lt;/PreferenceScreen&gt;
</code></pre>

<p><strong>pref_subscreen.xml (Nested PreferenceScreen)</strong></p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" &gt;

    &lt;PreferenceScreen
        android:key="subscreen"
        android:persistent="false"
        android:title="Test" &gt;
        &lt;Preference
            android:key="preference_to_click"
            android:persistent="false"
            android:title="preference_to_click" /&gt;
        &lt;Preference
            android:key="preference_to_remove"
            android:title="preference_to_remove" /&gt;
    &lt;/PreferenceScreen&gt;

&lt;/PreferenceScreen&gt;
</code></pre>

<p><strong>Diff of PrefFlatActivity.java and PrefSubscreenActivity.java</strong></p>

<pre><code>1c1
&lt; public class PrefFlatActivity extends PreferenceActivity {
---
&gt; public class PrefSubscreenActivity extends PreferenceActivity {
5,6c5,7
&lt;     public static final String PREFERENCE_TO_CLICK = "preference_to_click";
&lt;     public static final String PREFERENCE_TO_REMOVE = "preference_to_remove";
---
&gt;     private static final String PREFERENCE_TO_CLICK = PrefFlatActivity.PREFERENCE_TO_CLICK;
&gt;     private static final String PREFERENCE_TO_REMOVE = PrefFlatActivity.PREFERENCE_TO_REMOVE;
&gt;     private static final String PREFERENCE_SUBSCREEN = "subscreen";
15c16
&lt;         addPreferencesFromResource(R.xml.pref_flat);
---
&gt;         addPreferencesFromResource(R.xml.pref_subscreen);
28c29
&lt;             PreferenceScreen screen = getPreferenceScreen();
---
&gt;             PreferenceScreen screen = (PreferenceScreen) findPreference(PREFERENCE_SUBSCREEN);
</code></pre>

<p><strong>PrefFlatActivity.java (Working)</strong></p>

<pre><code>/**
 * Works as expected. Clicking toggles the "visibility" of the PREFERENCE_TO_REMOVE Preference.
 */
public class PrefFlatActivity extends PreferenceActivity {
    /**
     * Preference keys.
     */
    public static final String PREFERENCE_TO_CLICK = "preference_to_click";
    public static final String PREFERENCE_TO_REMOVE = "preference_to_remove";

    private final String PREF_NAME = getClass().getName() + ".pref";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getPreferenceManager().setSharedPreferencesName(PREF_NAME);
        addPreferencesFromResource(R.xml.pref_flat);

        findPreference(PREFERENCE_TO_CLICK)
            .setOnPreferenceClickListener(new OnFlatClickListener());
    }

    /**
     * Removes or adds Preference with key PREFERENCE_TO_REMOVE when clicked.
     */
    private class OnFlatClickListener implements OnPreferenceClickListener {
        private Preference mRescuedPreference;

        public boolean onPreferenceClick(Preference preference) {
            PreferenceScreen screen = getPreferenceScreen();
            Preference prefToRemove = screen.findPreference(PREFERENCE_TO_REMOVE);

            Log.d("test", "Found PREFERENCE_TO_REMOVE: " + (prefToRemove != null));

            if (prefToRemove != null) {
                screen.removePreference(prefToRemove);
                mRescuedPreference = prefToRemove; // Rescue reference to re-add it later.
            }

            else {
                screen.addPreference(mRescuedPreference);
            }

            return true;
        }
    }
}
</code></pre>

<p><strong>PrefSubscreenActivity.java (Nested, broken after orientation change)</strong></p>

<pre><code>/**
 * Broken after orientation change. Clicking does not remove/add PREFERENCE_TO_REMOVE.
 */
public class PrefSubscreenActivity extends PreferenceActivity {
    /**
     * Preference keys.
     */
    private static final String PREFERENCE_TO_CLICK = PrefFlatActivity.PREFERENCE_TO_CLICK;
    private static final String PREFERENCE_TO_REMOVE = PrefFlatActivity.PREFERENCE_TO_REMOVE;
    private static final String PREFERENCE_SUBSCREEN = "subscreen";

    private final String PREF_NAME = getClass().getName() + ".pref";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getPreferenceManager().setSharedPreferencesName(PREF_NAME);
        addPreferencesFromResource(R.xml.pref_subscreen);

        findPreference(PREFERENCE_TO_CLICK)
            .setOnPreferenceClickListener(new OnFlatClickListener());
    }

    /**
     * Removes or adds Preference with key PREFERENCE_TO_REMOVE when clicked.
     */
    private class OnFlatClickListener implements OnPreferenceClickListener {
        private Preference mRescuedPreference;

        public boolean onPreferenceClick(Preference preference) {
            PreferenceScreen screen = (PreferenceScreen) findPreference(PREFERENCE_SUBSCREEN);
            Preference prefToRemove = screen.findPreference(PREFERENCE_TO_REMOVE);

            Log.d("test", "Found PREFERENCE_TO_REMOVE: " + (prefToRemove != null));

            if (prefToRemove != null) {
                screen.removePreference(prefToRemove);
                mRescuedPreference = prefToRemove; // Rescue reference to re-add it later.
            }

            else {
                screen.addPreference(mRescuedPreference);
            }

            return true;
        }
    }
}
</code></pre>
