1

から特定の(キー付き)OnPreferenceClickListenerを削除する必要がある があります。Preferencepreference_to_removePreferenceScreen

問題は、ネストされた画面内にあり、画面の向きが変更された場合、ネストされた画面内にpreference_to_removeない場合に私のソリューションが機能することですが、機能しません。PreferenceScreen画面の向きが変更される前は、ネストされた画面も期待どおりに機能しています。

次のコードには 2 つのバージョンが含まれていPreferenceScreenますPreferenceScreen

画面の向きが変わった後、ネストされたバージョンでPreferencewith キーを削除できない理由は何ですか? フラットのみを使用し、疑似子として新しく開始するpreference_to_remove以外に、どのような解決策がありますか?PreferenceScreensIntentsPreferenceScreens

PS: 私はPreferenceActivityFroYo の互換性のために使用しています。

Test-Appで再現する方法

アプリを開く→フラットボタンをクリック→preference_to_click削除するものをクリックしpreference_to_removeます。→ 向き変更 → クリックで再度preference_to_click削除。preference_to_remove設定が削除されましたか? 成功!

アプリを開く→サブスクリーンボタンをクリック→テストをクリック→最初のテストからの手順を繰り返しますが、今回preference_to_removeは向きを変更した後は削除できません。

アプリのダウンロード (ソース)

pref_flat.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <Preference
        android:key="preference_to_click"
        android:persistent="false"
        android:title="preference_to_click" />
    <Preference
        android:key="preference_to_remove"
        android:title="preference_to_remove" />

</PreferenceScreen>

pref_subscreen.xml (ネストされた PreferenceScreen)

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <PreferenceScreen
        android:key="subscreen"
        android:persistent="false"
        android:title="Test" >
        <Preference
            android:key="preference_to_click"
            android:persistent="false"
            android:title="preference_to_click" />
        <Preference
            android:key="preference_to_remove"
            android:title="preference_to_remove" />
    </PreferenceScreen>

</PreferenceScreen>

PrefFlatActivity.java と PrefSubscreenActivity.java の違い

1c1
< public class PrefFlatActivity extends PreferenceActivity {
---
> public class PrefSubscreenActivity extends PreferenceActivity {
5,6c5,7
<     public static final String PREFERENCE_TO_CLICK = "preference_to_click";
<     public static final String PREFERENCE_TO_REMOVE = "preference_to_remove";
---
>     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";
15c16
<         addPreferencesFromResource(R.xml.pref_flat);
---
>         addPreferencesFromResource(R.xml.pref_subscreen);
28c29
<             PreferenceScreen screen = getPreferenceScreen();
---
>             PreferenceScreen screen = (PreferenceScreen) findPreference(PREFERENCE_SUBSCREEN);

PrefFlatActivity.java (動作中)

/**
 * 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;
        }
    }
}

PrefSubscreenActivity.java (ネストされ、向きの変更後に破損)

/**
 * 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;
        }
    }
}
4

1 に答える 1

1

編集:あなたが要求したようにこれを機能させるのに問題がありました. Preference私はs のソースと、それらが運のない状態をどのように処理するかを読んだので、おそらく明らかな何かが欠けているでしょう (それはよくあることではありませんか?)

私はいくつかのテストを行いましたが、ネストされたものを表示するために使用するPreferenceScreenおよび/または の状態が、私たちのどちらも予期しない方法で動作していると思います。たとえば、 a の代わりに aを使用した場合、この動作は見られません。DialogPreferenceScreenPreferenceCategoryPreferenceScreen

s を使用するこの方法Preferenceは非推奨であるため、いつでもフラグメントを使用して試すことができます。

http://developer.android.com/reference/android/preference/PreferenceActivity.html

ただし、従来の理由でこれを回避していると思われます。

別のオプションは、Preferenceプログラムで作成することです。

別の設定に応じてコードで設定画面を作成する

または、構成の変更を自分で処理することもできます。

http://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges
https://stackoverflow.com/questions/3542333/how-to-prevent-custom-views-from-losing-state-across-screen-orientation-changes/8127813#8127813
<activity ..
 android:configChanges="orientation|keyboardHidden" .. >

うまくいけば、あなたはこれをすぐに理解することができます. 最終的に解決策が浮かび上がると確信しています。そんなに難しいことはありません!ここで期待しています;)

元のソース (ほとんど) を以下に保持します。

    package com.example.removepref;

    import android.preference.Preference;
    import android.preference.Preference.OnPreferenceClickListener;
    import android.preference.PreferenceActivity;
    import android.preference.PreferenceScreen;
    import android.util.Log;


    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
        protected void onResume() {
            super.onResume();
            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;
            private boolean mPrefToRemoveVisible = true;
            
            public boolean onPreferenceClick(Preference preference) {
                // toggle visibility
                mPrefToRemoveVisible = !mPrefToRemoveVisible; 
                
                PreferenceScreen screen = (PreferenceScreen) findPreference(PREFERENCE_SUBSCREEN);
                Preference prefToRemove = screen.findPreference(PREFERENCE_TO_REMOVE);
                
                Log.d("test", "Found PREFERENCE_TO_REMOVE: " + (prefToRemove != null));
                Log.d("test", "And noted mPrefToRemoveVisible: " + mPrefToRemoveVisible);
                
                //Replaced the conditional blocks:
                if (mPrefToRemoveVisible && null == prefToRemove) {
                    boolean added = screen.addPreference(mRescuedPreference);
                    Log.d("test", "screen.addPreference(mRescuedPreference) success?" + added);
                } else if (!mPrefToRemoveVisible && null != prefToRemove) {
                    mRescuedPreference = prefToRemove;
                    boolean removed = screen.removePreference(prefToRemove);
                    Log.d("test", "screen.removePreference(mRescuedPreference) success?" + removed);
                }
                
                return true;
            }
        }
    }

推奨読書: http://developer.android.com/guide/topics/resources/runtime-changes.html

于 2012-10-19T14:53:32.370 に答える