6.1 问题
需要向用户显示一个简单的弹出式对话框来进行事件通知或展示一个选项列表。
6.2 解决方案
(API Level 1)
在向用户快速展示重要模态信息的场景中,AlertDialog是最高效的解决方案。它展示的内容可以很轻松地进行自定义,同时框架还提供一个方便的AlertDialog.Builder类来快速构建弹出式对话框。
6.3 实现机制
通过使用AlertDialog.Builder,可以构建类似的报警对话框,但包含不同的额外选项。AlertDialog在创建简单的弹出式对话框来获得用户反馈时是一个非常有用的类。通过AlertDialog.Builder,可以很容易在一个简洁的小部件中添加单选或多选列表、按钮和消息字符串。
为了说明这一点,让我们用AlertDialog创建一个和以前一样的弹出式选择框。这一次,我们将在选项列表的底增加Cancel按钮(参见以下代码)。
使用了AlertDialog的动作菜单
public class DialogActivity extends Activity
implements DialogInterface.OnClickListener, View.OnClickListener {
private static final String[] ZONES =
{"Pacific Time", "Mountain Time", "Central Time", "Eastern Time", "Atlantic Time"};
Button mButton;
AlertDialog mActions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mButton = new Button(this);
mButton.setText("Click for Time Zones");
mButton.setOnClickListener(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select Time Zone");
builder.setItems(ZONES, this);
//这里的取消动作只会让对话框消失,但在用户单击Cancel按钮时,
// 也可以添加另一个监听器来处理一些其他的操作
builder.setNegativeButton("Cancel", null);
mActions = builder.create();
setContentView(mButton);
}
//这里处理列表的选择事件
@Override
public void onClick(DialogInterface dialog, int which) {
String selected = ZONES[which];
mButton.setText(selected);
}
//这里处理按钮的单击事件 (弹出对话框)
@Override
public void onClick(View v) {
mActions.show();
}
}
本例中,我们创建了一个新的AlertDialog.Builder实例并使用它的便捷方法添加了如下条目:
- 标题 : 通过setTitle()设置。
- 选项列表,通过setItems()和一个字符串数组(也可以是数组资源)设置。
- Cancel按钮,通过setNegativeButton()设置。
当选择列表中的一个选项时,我们关联到列表项的监听器会返回所选择的选项(索引是之前提供的数组的索引,从0开始),然后我们就可以根据用户的选择来更新按钮上的文本信息。对于Cancel按钮,因为我们只想在按下Cancel按钮时关闭对话框,所以我们为Cancel按钮传入的监听器为null。如果在按下Cancel按钮时还想处理一些重要的工作,可以向setNegativeButton()方法传入其他的监听器。
另外,还要其他的一些选项可以设置除了选项列表之外的对话框中的内容:
- setMessage()可以为对话框的内容设置除了选项列表之外的对话框中的内容。
- setSingleChoiceItems()和setMultiChoiceItems()会创建一个与本例类似的列表,但每个选项是以复选框的方式显示的。
- setView()可以为对话框的内容使用任意自定义视图。
现在,按钮按下后得到的应用程序的外观如图所示:
带有选项列表的AlertDialog
自定义列表条目
AlertDialog.Builder允许传入一个自定义的ListAdapter作为对话框中显示列表条目的数据源,这也意味着我们可以自定义列表中的每一行的布局来向用户显示更加详细的信息。在以下两个代码中改进了之前的示例,为每一行使用自定义的行布局来显示每个条目的其他信息。
res/layout.list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:minHeight="?android:attr/listPreferredItemHeight">
<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/text_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</RelativeLayout>
带有自定义布局的AlertDialog
public class CustomItemActivity extends Activity
implements DialogInterface.OnClickListener, View.OnClickListener {
private static final String[] ZONES =
{"Pacific Time", "Mountain Time", "Central Time", "Eastern Time", "Atlantic Time"};
private static final String[] OFFSETS =
{"GMT-08:00", "GMT-07:00", "GMT-06:00", "GMT-05:00", "GMT-04:00"};
Button mButton;
AlertDialog mActions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mButton = new Button(this);
mButton.setText("Click for Time Zones");
mButton.setOnClickListener(this);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
row = getLayoutInflater().inflate(R.layout.list_item, parent, false);
}
TextView name = (TextView) row.findViewById(R.id.text_name);
TextView detail = (TextView) row.findViewById(R.id.text_detail);
name.setText(ZONES[position]);
detail.setText(OFFSETS[position]);
return row;
}
@Override
public int getCount() {
return ZONES.length;
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select Time Zone");
builder.setAdapter(adapter, this);
//这里的取消动作只会让对话框消失,但在用户单击Cancel按钮时,
//也可以添加一个监听器来处理一些其他的操作
builder.setNegativeButton("Cancel", null);
mActions = builder.create();
setContentView(mButton);
}
//这里处理列表的选择事件
@Override
public void onClick(DialogInterface dialog, int which) {
String selected = ZONES[which];
mButton.setText(selected);
}
//这里处理按钮的单击事件 (弹出对话框)
@Override
public void onClick(View v) {
mActions.show();
}
}
这里我们为生成器提供了一个ArrayAdapter,而不是简单地传入了选项数组。ArrayAdapter有getView()的自定义实现,会返回一个XML中自定义布局,我们现在可以显示GMT偏移值和时区名称。之后会进一步讨论自定义适配器的特性。如图显示了新的、更加实用的弹出式对话框。
带有自定义条目的AlertDialog
网友评论