更改屏幕方向时,我的ListPreference不会保留值

时间:2014-05-05 22:41:52

标签: android android-fragments

我已经坚持了几天,尝试了不同的解决方法。 当我更改屏幕方向时,首选项摘要会丢失其值。

我有一个自定义ListPreference,当用户点击时,会为好友弹出两个选项 - 我自己和其他一些(在实际程序中,用户从联系人中选择好友)。

我将摘要设置为所选好友的电子邮件地址。

点击首选项弹出列表首选项,根据点击的内容,显示我自己,或联系选择器以选择好友。

enter image description here

'自己'被选中

enter image description here

翻转手机失去了好友

enter image description here

这是一个剥离的工作程序,以显示要点。

类BuddyPreference2

public class BuddyPreference2 extends ListPreference {
    String buddy;
    private static final String TAG = "REGU";

    public BuddyPreference2(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onDialogClosed(boolean positiveResult) {
        if (positiveResult) {
            persistString((String) buddy);
        }
        super.onDialogClosed(positiveResult);
    }
    @Override
    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
        super.onSetInitialValue(restoreValue, defaultValue);
        if (restoreValue) {
            // Restore existing state
            buddy = this.getPersistedString("none set");
        } else {
            // Set default state from the XML attribute
            buddy = (String) defaultValue;
            persistString(buddy);
        }
    }
    /*
     * (non-Javadoc)
     * 
     * @see android.preference.ListPreference#setValue(java.lang.String)
     */
    @Override
    public void setValue(String value) {
        String s = new String(value);
        super.setValue(s);
    }
    @Override
    protected View onCreateDialogView() {
        View view = super.onCreateDialogView();

        return view;
    }
}

user_prefs.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="@+id/pref_screen" >
    <com.mypreferences.BuddyPreference2
        android:entries="@array/buddy_entry"
        android:entryValues="@array/buddy_value"
        android:key="buddy_entry"
        android:summary="my buddy"
        android:title="my buddy" />
</PreferenceScreen>

class EditAlertPreferencesActivity

public class EditAlertPreferencesActivity extends Activity {


    static final String BUDDY = "buddy_entry";

    static final String TAG = "REGU";
    private static final int CONTACT_PICKER_RESULT = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.user_prefs_fragment);
    }

    // Fragment that displays the mesg preference
    public static class UserPreferenceFragment extends PreferenceFragment {

        protected static final String TAG = "REGU";
        private OnSharedPreferenceChangeListener mListener;
        private Preference buddyPreference;

        String myEmailAddress;

        String getMyEmailAddress() {
                    return "Myself" + " <me@my.com>";
        }

        public void setBuddySummary(String s) {
            buddyPreference.setSummary(s);
        }


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

            // Load the preferences from an XML resource
            addPreferencesFromResource(R.xml.user_prefs);

            buddyPreference = (Preference) getPreferenceManager().findPreference(BUDDY);

            buddyPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    String buddyChoice = (String) newValue;
                    if (buddyChoice.equals(getString(R.string.select))) {
                        Toast.makeText(getActivity(), "pick a contact", Toast.LENGTH_SHORT);
                        pickContact();
                    } else {
                        buddyPreference.setSummary(myEmailAddress);
                    }
                    return false;
                }
            });

            // Attach a listener to update summary when msg changes
            mListener = new OnSharedPreferenceChangeListener() {
                @Override
                public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
                        String key) {
                    if (key.equals(BUDDY)) {
                        buddyPreference.setSummary(sharedPreferences.getString(BUDDY, "none set"));
                    } else {
                        Log.e(TAG, "error; I do not recognize key " + key);
                    }
                }
            };

            // Get SharedPreferences object managed by the PreferenceManager for
            // this Fragment
            SharedPreferences prefs = getPreferenceManager().getSharedPreferences();

            // Register a listener on the SharedPreferences object
            prefs.registerOnSharedPreferenceChangeListener(mListener);

            // Invoke callback manually to display the msg
            mListener.onSharedPreferenceChanged(prefs, BUDDY);
        }

        /*
         * (non-Javadoc)
         * 
         * @see android.preference.PreferenceFragment#onCreateView(android.view.
         * LayoutInflater, android.view.ViewGroup, android.os.Bundle)
         */
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            return super.onCreateView(inflater, container, savedInstanceState);
        }

        public void pickContact() {
                            String buddyEmailAddress = "Some Buddy " + " <buddy@email.com>";
                            setBuddySummary(buddyEmailAddress);
        }
    }
}

user_prefs_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.mypreferences.EditAlertPreferencesActivity$UserPreferenceFragment"
    android:orientation="vertical" 
    android:id="@+id/userPreferenceFragment">

</fragment>

arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="buddy_entry">
        <item>myself</item>
        <item>select a contact</item>
    </string-array>
    <string-array name="buddy_value">
        <item>myself</item>
        <item>select</item>
    </string-array>
</resources>

class PreferencesActivityExample

public class PreferencesActivityExample extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Open a User Preferences Entry Activity 
        final Button button = (Button) findViewById(R.id.check_pref_button);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(
                        PreferencesActivityExample.this,
                        EditAlertPreferencesActivity.class));
            }
        });

    }
}

的strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="select">select</string>
</resources>

2 个答案:

答案 0 :(得分:9)

问题是对话框中选择的Preference值未保存/更新。 您可以轻松验证此Close the Activity and launch gain. You will still see the default value,并注意orientation更改。

FIX:您需要返回true来更新preference中的新值。

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    // do all your other stuff here            
    return true;
}

为True以使用新值更新“首选项”的状态。

答案 1 :(得分:0)

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

    final ListPreference listPreferenceCategory = (ListPreference) findPreference("pref_list_category");
    listPreferenceCategory.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            String category = (String) newValue;
            CharSequence[] listEntries = listPreferenceCategory.getEntries();
            int indexValue = listPreferenceCategory.findIndexOfValue(category);
            listPreferenceCategory.setSummary(listEntries[indexValue]);
            return true;
        }
    });
}

在xml中:

 <ListPreference
        android:dialogTitle="@string/pref_category"
        android:entries="@array/categories"
        android:summary="@string/pref_category"
        android:entryValues="@array/categories_value"
        android:key="pref_list_category"
        android:title="@string/pref_category"/>

这是我的工作代码。试试吧!