Is it possible to force user to select at least one option in AlertDialog setMultiChoiceItems()?

30 Views Asked by At

I have a DialogFragment that displays three options to the user and a positive button. The dialog works as a filter, so the user can check all options, two or one, and based on that, I show some items or others.

Currently, it works, but also the user can uncheck all choices and tap on the apply button, making my Fragment to do not display any item. I would like to show a message to the user before this happens, warning him/she that at least 1 option must be checked, and hence, avoiding the dialog to be closed until the user dismisses the dialog or checks at least one choice and tap accept.

This is my code:

public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
    builder.setTitle(this.getResources().getString(R.string.filter_title));
    builder.setMultiChoiceItems(this.choices, this.selection,
            new DialogInterface.OnMultiChoiceClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i, boolean b) {
                    changeSelection(i, b);
                }
            });
    builder.setPositiveButton(R.string.filter_accept, 
            new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            listener.onDialogPositiveClick(ListItemsFragment.this);
        }
    });
    return builder.create();
}

Thank you!

1

There are 1 best solutions below

2
Iván Garza Bermea On

Given the code you've shared, I don't really know what the function changeSelection(..) is doing, or how are you handling responses from your multi choice listener.

Nevertheless, I think that inside the positive button's click listener callback, you should check that any value inside your this.selection boolean array is currently true, and only move forward if that's the case. The selector array should be getting updated on the MultiChoiceItems listener, and this should enable you to operate based on the present data at all times.

In short, I would try to do something like:

public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
    builder.setTitle(this.getResources().getString(R.string.filter_title));
    builder.setMultiChoiceItems(this.choices, this.selection,
            new DialogInterface.OnMultiChoiceClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int index, boolean isChecked) {
                    // Keep track of the selected items
                    selection[index] = isChecked;
                }
            });
    builder.setPositiveButton(R.string.filter_accept, 
            new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            for (boolean isSelected : selection) {
                if (isSelected) {
                    // Found at least one selected option -- carry on
                    listener.onDialogPositiveClick(ListItemsFragment.this);
                } else {
                    // Unable to find not a single selected option
                    //TODO: Handle not having a single option selected
                }
            }
        }
    });
    return builder.create();
}

Where the MultiChoiceItems selector is constantly keeping track of the latests selections (you may already be doing this inside changeSelection(..)), and you don't let the positive button click advance unless we can confirm that there is indeed at least one item currently selected.