Persist AlertDialog checked options

2019-03-03 05:21发布

问题:

I've been struggling with this for more than two weeks. been on all the SO questions about sharedpreferenes and other 'hacks' to persist a multiple choice alertdialog. but unfortunately i still can't make it work.

Can someone please explain to me how to make this thing work ? my multiple choice alertdialog works. but i still can't save the selected items..

My code :

    public class TimelineSettings extends DialogFragment {
    Context context;
    final ArrayList selected_categories = new ArrayList();
    final String[]items = {"Fourniture","Nourriture","Voyages","Habillement","Médias","Autres"};
    TinyDB tinydb = new TinyDB(context);
    private SharedPreferences sharedPreference;
    private SharedPreferences.Editor sharedPrefEditor;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Set the dialog title
        builder.setTitle("Choisissez vos paramètres")
                .setMultiChoiceItems(items, null,
                        new DialogInterface.OnMultiChoiceClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int indexselected,
                                                boolean isChecked) {
                                if (isChecked) {
                                    // If the user checked the item, add it to the selected items
                                    selected_categories.add(indexselected);
                                } else if (selected_categories.contains(indexselected)) {
                                    // Else, if the item is already in the array, remove it
                                    selected_categories.remove(Integer.valueOf(indexselected));
                                }
                            }
                        })
                        // Set the action buttons
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                    tinydb.putList("selected",selected_categories);
                    }
                })
                .setNegativeButton("Annuler", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                    }
                });
        return builder.create();
    }
}

Thanks for your help.

PS : I came across this answer, if you can explain to me how to make this work, it would be great.

回答1:

Be careful because you are saving Integers in preferences and then you are converting an ArrayList of Integers to an ArrayList of Strings. This may cause an Exception. Use ArrayLists of Strings everywhere instead.

You are only missing the part where, before you show your DialogFragment, you have to read your saved choices and check them in your DialogFragment.

There are easiest ways of doing what you want but let's take this approach:

As you have noticed, the setMultiChoiceItems() method receives a String[] as the items of your DialogFragment and a boolean [] to define if they are checked or not. We are going to use this array to persist our choices. This array must have the same length as the items array and will be initially set to false.

On the first time you launch the DialogFragment, no items are checked. On the second time, when you already have items checked, you are going to read those choices from TinyDB and populate the boolean array with a for statement. Then you feed it to the DialogFragment builder.

The items that were saved will appear as checked on the DialogFragment, as you wished to do.

Here is the complete changed and working code:

    public class TimelineSettings extends DialogFragment {
    ArrayList<String> selected_categories = new ArrayList<String>();
    final String[]items = {"Fourniture","Nourriture","Voyages","Habillement","Médias","Autres"};
    boolean[] itemsChecked = {false, false, false, false, false, false};
    TinyDB tinydb;
    private SharedPreferences sharedPreference;
    private SharedPreferences.Editor sharedPrefEditor;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        tinydb = new TinyDB(getActivity());
        selected_categories = tinydb.getList("selected");

        for(int i=0;i<itemsChecked.length;i++){
            if(selected_categories.contains((String)String.valueOf(i)))
                    itemsChecked[i]=true;
        }

        // Set the dialog title
        builder.setTitle("Choisissez vos paramètres")
                .setMultiChoiceItems(items, itemsChecked,
                        new DialogInterface.OnMultiChoiceClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int indexselected,
                                                boolean isChecked) {
                                if (isChecked) {
                                    // If the user checked the item, add it to the selected items
                                    if(!selected_categories.contains((String)String.valueOf(indexselected))){
                                        selected_categories.add(String.valueOf(indexselected));
                                        itemsChecked[indexselected]=true;
                                    }
                                } else if (selected_categories.contains((String)String.valueOf(indexselected))) {
                                    // Else, if the item is already in the array, remove it
                                    selected_categories.remove((String)String.valueOf(indexselected));
                                    itemsChecked[indexselected]=false;
                                }
                            }
                        })
                        // Set the action buttons
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        tinydb.putList("selected",selected_categories);
                    }
                })
                .setNegativeButton("Annuler", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                    }
                });
        return builder.create();
    }
}