Monday, March 8, 2010

Modifying an Alert Dialog's List Items after Creation

Category: UI
Subcategory: AlertDialog, ListView
Android Platform: 1.5, Google APIs 3
Referenced Classes: android.app.AlertDialog, android.widget.ListAdapter, android.widget.ListView

There are cases when you need to change the text of an Alert Dialog's List Items, after the Alert Dialog has already been created. This is typical when working with the Dialog lifecycle of an Activity (i.e. Activity.onCreateDialog(…), Activity.onPrepareDialog(…)). Take the following example:
code snippet
protected Dialog onCreateDialog(int id)
{


final CharSequence[] items = {"Red", "Green", "Blue"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setItems(items, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int item) {
        Toast.makeText(getApplicationContext(),
items[item], Toast.LENGTH_SHORT).show();
    }
});
AlertDialog dropdown = builder.create();


}
Suppose, following some user action in the Activity UI, you want to append text to the first list item of the drop down. So, instead of displaying "Red", the first list item should read "Red {actionResultValue}". First, you need to modify the above code, accordingly:
code snippet
protected Dialog onCreateDialog(int id)
{


final CharSequence[] items = {
new StringBuilder(),
"Green",
"Blue"}; // or any non-immutable CharSequence


}
Now, when Activity.onCreateDialog(…) is called, the first list item is a pseudo placeholder. Next, set the text of the first list item in Activity.onPrepareDialog(…) with the following:
code snippet
protected void onPrepareDialog(int id, Dialog dialog)
{


String actionResultValue = ...
ListView dropdown= ((AlertDialog) dialog).getListView();
ListAdapter dropdownAdapter= dropdown.getAdapter();
//
StringBuilder listItem0Text=
(StringBuilder) dropdownAdapter.getItem(0);
listItem0Text.delete(0, listItem0Text.length());
listItem0Text.append("Red " + actionResultValue);
//
dropdown.invalidateViews();


}
Note, the call to dropdown.invalidateViews(). Without this, the text changes will not display.

3 comments:

  1. I have tried with with a dialog built using AlertDialog.builder() and get a ClassCastException when I get the item and try and cast to StringBuilder to modify it.

    Any hints, please email ideas to andrew at mackenzie-serres.net

    thanks anyway

    ReplyDelete
  2. I just ran the example on SDK version 8 and it worked without issue. What version are you using? Can you send me your code?

    ReplyDelete
  3. May it is easier than this just setting a new adapter to the listivew with the required items. It works for me.

    ReplyDelete