Looking for suggestions on how to reuse AlertDialogs to confirm actions of contextual menus on the items of an ActivityList
Posted
by
Ozone
on Stack Overflow
See other posts from Stack Overflow
or by Ozone
Published on 2010-12-29T02:51:13Z
Indexed on
2010/12/29
2:53 UTC
Read the original article
Hit count: 191
android
I use a ListActivity
to display a list of items. The user can long-press an item in the list to display a contextual menu. This menu contains among other things an option to delete the long-pressed item. When the user selects this option, a dialog pops up asking for confirmation of the deletion. Upon confirmation, the item is deleted from the list.
I would like to reuse the AlertDialog
as much as possible. My attempts at using onPrepareDialog(int, View, Bundle)
have been defeated by the fact that the Bundle
is not passed to the DialogInterface.OnClickListener
. I end up having to recreate a listener on every invocation.
I see several ways to solve this:
- recreate the dialog on every occasion (pros: simple, cons: wasteful)
- keep the
DialogInterface.OnClickListener
in a field on theListActivity
and keep the item to be deleted as a field of the listener. (pros: no memory waste, cons: need to manage state). Q: is this safe? - have
onPrepareDialog
update the title, and bind newView.OnClickListener
s on the buttons of theAlertDialog
. (pros: limit waste, cons: newView.OnClickListener
on every invocation).
If DialogInterface.OnClickListener
accepted a Bundle
, I wouldn't have to jump through hoops to keep track of the item being deleted.
This is not a blocker, but I would love to see an elegant solution. I would love to hear your suggestions :)
Here is the code for option #1, if you want to play with this:
public class Example extends ListActivity {
private static final int CONFIRM_DELETE_DIALOG = 1;
private static final String POSITION_KEY = "position";
private ArrayAdapter<String> mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new ArrayAdapter<String>(
this, android.R.layout.simple_list_item_1,
new String[] { "one", "two" });
setListAdapter(mAdapter);
registerForContextMenu(getListView());
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.my_lovely_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.delete_item:
Bundle bundle = new Bundle();
bundle.putInt(POSITION_KEY, info.position);
showDialog(CONFIRM_DELETE_DIALOG, bundle);
return true;
default:
return super.onContextItemSelected(item);
}
}
@Override
protected Dialog onCreateDialog(int id, Bundle args) {
switch (id) {
case CONFIRM_DELETE_DIALOG:
final int position = args.getInt(POSITION_KEY);
AlertDialog.Builder builder = new AlertDialog.Builder();
builder.setCancelable(false);
builder.setTitle(String.format(
getString(R.string.confirm_delete), mAdapter.getItem(position)));
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
mAdapter.remove(mAdapter.getItem(position));
// Dismiss the dialog to ensure OnDismissListeners are notified.
dialog.dismiss();
break;
case DialogInterface.BUTTON_NEGATIVE:
// Cancel the dialog to ensure OnCancelListeners are notified.
dialog.cancel();
break;
}
// Remove the dialog so it is re-created next time it is required.
removeDialog(CONFIRM_DELETE_DIALOG);
}
};
builder.setPositiveButton(android.R.string.yes, listener);
builder.setNegativeButton(android.R.string.no, listener);
return builder.create();
default:
return super.onCreateDialog(id, args);
}
}
}
© Stack Overflow or respective owner