androidandroid-preferencesandroid-settingsandroid-multiselectlistpreference

Android MultiSelectListPreference with priority order


I'm new to Android. I want to use MultiSelectListPreference for my case.

But I encounter a problem: My list need to keep the order of element. Assume there're 5 elements:

0 - Tom
1 - David
2 - Bob
3 - Mary
4 - Chris

and user choose 0, 2, 3. Then the list is must be in the order as below:

Tom, Bob, Mary

But the MultiSelectListPreference stores setting in Set<String>, not ArrayList<String>, so it's not sure for this order because of Set.

How can I make sure this order? Thank you.


Solution

  • camdaochemgio, I understood your question even before your edit.

    Since we are talking about a Set (that stores unique values) , This getValues() function needs to be fed into your own revertValues function that translates the values into indexes - based on your preset of the data. I asked for your code so I could express myself by writing the solution to this in your own style/terminology.

    The Solution:

    I noticed in the docs of MultiSelectListPreference the following method :

    int findIndexOfValue(String value)
    

    But you do not store such reference to the object, So I created this class to extend MultiSelectListPreference (in new file!) :

    public class DataHolder extends MultiSelectListPreference {
    
        // note: AttributeSet  is needed in super class
        public DataHolder(Context context,AttributeSet attrs) {   
            super(context, attrs);
    
            List<CharSequence> entries = new ArrayList<CharSequence>();
            List<CharSequence> entriesValues = new ArrayList<CharSequence>();
    
            /** We could use the String Array like you did in your Q, 
             * But I preffer this way of populating data - 
             * It keeps things open and unlimitted.
             * If you really want the data picked up from the xml , just use : 
             * context.getResources().getStringArray(R.array.entries)  and
             * context.getResources().getStringArray(R.array.entryValues) 
             * */
    
            entries.add("0");
            entries.add("1");
            entries.add("2");
            entries.add("3");
            entries.add("4");
            entriesValues.add("Tom");
            entriesValues.add("David");
            entriesValues.add("Bob");
            entriesValues.add("Mary");
            entriesValues.add("Chris");
    
            setEntries(entries.toArray(new CharSequence[5]));
            setEntryValues(entriesValues.toArray(new CharSequence[5]));
        }
    }
    

    Now we need to plug it in your listener. In your SettingsFragment class , just add a new field :

    private DataHolder dh = null;
    

    And change the constructor to accept it and initialize it :

    public SettingsFragment(Context c) {
        dh = new DataHolder(c,null);
    }
    

    Next step: remove the reference to the data from the xml. It should look like this now :

    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
        <com.example.multiselectpref.DataHolder
            android:key="pref_key_name_choice"
            android:title="@string/name_choice"
        />
    </PreferenceScreen>
    

    Back to your listener, in onSharedPreferenceChanged method , You can change the toast to :

    toast_message += (dh.findIndexOfValue(name) + ": "+name+"    , ");
    

    Works for me.. (code committed to fork @ https://github.com/li3ro/MultiSelectPref)