Reputation: 1109
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
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
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
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