Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
440 views
in Technique[技术] by (71.8m points)

android - MultiSelectListPreference not storing values?

I'm rather new to Android App developing so maybe I'm just making a simple newbie mistake, but here's my problem: I have 2 simple Activities, MainActivity and SettingsActivity. In MainActivity I have a button which displays SettingsActivity. Within SettingsActivity I include a PreferenceFragment SettingsFragment and display a ButtonBar at the bottom of the Activity. Within the SettingsFragment I have a MultiSelectListPreference defined as follows:

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

        <MultiSelectListPreference
            android:key="@string/key_list_schedule"
            android:title="@string/title_schedule_list"
            android:dialogTitle="@string/title_schedule_list"
            android:entries="@array/list_weekdays"
            android:entryValues="@array/list_weekdays"
            android:defaultValue="@array/empty_list"
            android:persistent="true"/>
    </PreferenceCategory>

</PreferenceScreen>

Now when I select that Preference it shows me the list with all the entries as defined in the array, I can select multiple entries and when I confirm the dialog the values are in fact stored in the SharedPreferences under the defined key. But if I now show the Preference again it will show me previously selected items as selected, but the values are no longer stored within the SharedPreferences, and after some fiddling around I had to realize that the values in the SharedPreferences apparently get wiped as soon as the dialog is shown.

So now my questions are: is this normal/intended behavior or is this a bug? And how can I work around this? I already tried making my own implementation of MultiSelectListPreference and override the onPrepareDialogBuilder method like this

@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder)
{
    super.onPrepareDialogBuilder(builder);

    Log.i("mmslp", Arrays.deepToString(PreferenceManager.getDefaultSharedPreferences(getContext()).getStringSet(getKey(), new HashSet<String>()).toArray()));
    setValues(PreferenceManager.getDefaultSharedPreferences(getContext()).getStringSet(getKey(), new HashSet<String>()));
}

but the values are apparently wiped already at this point.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I spent some time yesterday on this and am now convinced that it is not intended like that, but actually broken - someone confused reference by pointer and by value. ;-)

Seems to be fixed in the more current versions of Android (since 4.1) though: https://code.google.com/p/android/issues/detail?id=22807

The way I solved it now for the previous versions of Android is to override the setValues method in my implementation of MultiSelectListPreference and just copy the values into a new object:

@Override
public void setValues( Set<String> values ) {

    //Workaround for https://code.google.com/p/android/issues/detail?id=22807
    final Set<String> newValues = new HashSet<String>();
    newValues.addAll( values );
    super.setValues( newValues );
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...