GFlam
GFlam

Reputation: 1109

Android checkbox dialog (easy)

I have a dialog with checkboxes, and I was trying to do different things when options are selected and when OK is pressed.

I thought I knew what I was doing after reading some tutorials, but when I press OK it just toasts "Everything" even if it isn't checked. So it seems that my if statements are not working correctly, but I don't know why.

What am I doing wrong and how do I fix it?

    final CharSequence[] items = {"Item 1", "Item 2", "Item 3"};
    final boolean[] states = {false, false, false};
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("What would you like to do?");

    builder.setMultiChoiceItems(items, states, new DialogInterface.OnMultiChoiceClickListener(){
        public void onClick(DialogInterface dialogInterface, int item, boolean state) {
        }
    });

    builder.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            SparseBooleanArray CheCked = ((AlertDialog)dialog).getListView().getCheckedItemPositions();
            if(CheCked.get(CheCked.keyAt(0)) == true){
                Toast.makeText(Backup.this, "Item 1", Toast.LENGTH_SHORT).show();
            }
            if(CheCked.get(CheCked.keyAt(1)) == true){
                Toast.makeText(Backup.this, "Item 2", Toast.LENGTH_SHORT).show();
            }
            if(CheCked.get(CheCked.keyAt(2)) == true){
                Toast.makeText(Backup.this, "Item 3", Toast.LENGTH_SHORT).show();
            }
        }
    });

    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
             dialog.cancel();
        }
    });

    builder.create().show();
}

Upvotes: 14

Views: 22397

Answers (3)

Collins Mann
Collins Mann

Reputation: 21

This should help:

.setMultiChoiceItems(
    items, itemsChecked,
    new DialogInterface.OnMultiChoiceClickListener() {
        @Override
        public void onClick(DialogInterface dialog,
                            int which, boolean isChecked) {
            Toast.makeText(
                getBaseContext(),
                items[which]
                        + (isChecked ? " checked!"
                                : " unchecked!"),
                Toast.LENGTH_SHORT).show();
        }
    }
)

But then how do you use the checked items in another class?

Upvotes: 2

rekaszeru
rekaszeru

Reputation: 19220

The problem is that you use keyAt, which, according to the API documentation

returns the key from the indexth key-value mapping that this SparseBooleanArray stores.

and this SparseBooleanArray contains only the checked items of your list (getCheckedItemPositions)!

So if you check two items of three, then the CheCked member will contain two items, and when you call keyAt(2) it will return 0 (not IndexOutOfBoundsException, though at that position the map does not hold a value).

You should simply use the get method of this SparseBooleanArray, with the item positions from your ListView as arguments:

builder.setPositiveButton("Okay", new DialogInterface.OnClickListener()
{
    public void onClick(DialogInterface dialog, int id)
    {
        SparseBooleanArray CheCked = ((AlertDialog) dialog).getListView().getCheckedItemPositions();
        if (CheCked.get(0))
        {
            Toast.makeText(TmpActivity2.this, "Item 1", Toast.LENGTH_SHORT).show();
        }
        if (CheCked.get(1))
        {
            Toast.makeText(TmpActivity2.this, "Item 2", Toast.LENGTH_SHORT).show();
        }
        if (CheCked.get(2))
        {
            Toast.makeText(TmpActivity2.this, "Item 3", Toast.LENGTH_SHORT).show();
        }
    }
});

You can also lose the == true part of the if clause, but that's just semantics.

If you take a look at the API documentation of the getCheckedItemPositions method, you find this solution:

Returns:
A SparseBooleanArray which will return true for each call to get(int position) where position is a position in the list, or null if the choice mode is set to CHOICE_MODE_NONE.

Upvotes: 7

evilone
evilone

Reputation: 22740

I would do it like this for example:

public class Main extends Activity {

    CharSequence[] items = {"Google", "Apple", "Microsoft"};
    boolean[] itemsChecked = new boolean[items.length];

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button btn = (Button) findViewById(R.id.btnDialog);
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showDialog(0);
            }
        });
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case 0:
            return new AlertDialog.Builder(this)
            .setIcon(R.drawable.icon)
            .setTitle("Dialog with simple text")
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    for (int i = 0; i < items.length; i++) {
                    if (itemsChecked[i]) {
                        Toast.makeText(getBaseContext(), items[i] + " checked!", Toast.LENGTH_LONG).show();
                    }
                }
                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Toast.makeText(getBaseContext(), "Cancel clicked!", Toast.LENGTH_LONG).show();
                }
            })
            .setMultiChoiceItems(items, itemsChecked, new DialogInterface.OnMultiChoiceClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                    Toast.makeText(getBaseContext(), items[which] + (isChecked ? "checked!" : "unchecked!"), Toast.LENGTH_SHORT).show();
                }
            })
            .create();
        }

        return null;
    }


}

Upvotes: 11

Related Questions