6.1 問題
需要向用戶顯示一個(gè)簡單的彈出式對(duì)話框來進(jìn)行事件通知或展示一個(gè)選項(xiàng)列表。
6.2 解決方案
(API Level 1)
在向用戶快速展示重要模態(tài)信息的場(chǎng)景中,AlertDialog是最高效的解決方案。它展示的內(nèi)容可以很輕松地進(jìn)行自定義,同時(shí)框架還提供一個(gè)方便的AlertDialog.Builder類來快速構(gòu)建彈出式對(duì)話框。
6.3 實(shí)現(xiàn)機(jī)制
通過使用AlertDialog.Builder,可以構(gòu)建類似的報(bào)警對(duì)話框,但包含不同的額外選項(xiàng)。AlertDialog在創(chuàng)建簡單的彈出式對(duì)話框來獲得用戶反饋時(shí)是一個(gè)非常有用的類。通過AlertDialog.Builder,可以很容易在一個(gè)簡潔的小部件中添加單選或多選列表、按鈕和消息字符串。
為了說明這一點(diǎn),讓我們用AlertDialog創(chuàng)建一個(gè)和以前一樣的彈出式選擇框。這一次,我們將在選項(xiàng)列表的底增加Cancel按鈕(參見以下代碼)。
使用了AlertDialog的動(dòng)作菜單
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);
//這里的取消動(dòng)作只會(huì)讓對(duì)話框消失,但在用戶單擊Cancel按鈕時(shí),
// 也可以添加另一個(gè)監(jiān)聽器來處理一些其他的操作
builder.setNegativeButton("Cancel", null);
mActions = builder.create();
setContentView(mButton);
}
//這里處理列表的選擇事件
@Override
public void onClick(DialogInterface dialog, int which) {
String selected = ZONES[which];
mButton.setText(selected);
}
//這里處理按鈕的單擊事件 (彈出對(duì)話框)
@Override
public void onClick(View v) {
mActions.show();
}
}
本例中,我們創(chuàng)建了一個(gè)新的AlertDialog.Builder實(shí)例并使用它的便捷方法添加了如下條目:
- 標(biāo)題 : 通過setTitle()設(shè)置。
- 選項(xiàng)列表,通過setItems()和一個(gè)字符串?dāng)?shù)組(也可以是數(shù)組資源)設(shè)置。
- Cancel按鈕,通過setNegativeButton()設(shè)置。
當(dāng)選擇列表中的一個(gè)選項(xiàng)時(shí),我們關(guān)聯(lián)到列表項(xiàng)的監(jiān)聽器會(huì)返回所選擇的選項(xiàng)(索引是之前提供的數(shù)組的索引,從0開始),然后我們就可以根據(jù)用戶的選擇來更新按鈕上的文本信息。對(duì)于Cancel按鈕,因?yàn)槲覀冎幌朐诎聪翪ancel按鈕時(shí)關(guān)閉對(duì)話框,所以我們?yōu)镃ancel按鈕傳入的監(jiān)聽器為null。如果在按下Cancel按鈕時(shí)還想處理一些重要的工作,可以向setNegativeButton()方法傳入其他的監(jiān)聽器。
另外,還要其他的一些選項(xiàng)可以設(shè)置除了選項(xiàng)列表之外的對(duì)話框中的內(nèi)容:
- setMessage()可以為對(duì)話框的內(nèi)容設(shè)置除了選項(xiàng)列表之外的對(duì)話框中的內(nèi)容。
- setSingleChoiceItems()和setMultiChoiceItems()會(huì)創(chuàng)建一個(gè)與本例類似的列表,但每個(gè)選項(xiàng)是以復(fù)選框的方式顯示的。
- setView()可以為對(duì)話框的內(nèi)容使用任意自定義視圖。
現(xiàn)在,按鈕按下后得到的應(yīng)用程序的外觀如圖所示:
自定義列表?xiàng)l目
AlertDialog.Builder允許傳入一個(gè)自定義的ListAdapter作為對(duì)話框中顯示列表?xiàng)l目的數(shù)據(jù)源,這也意味著我們可以自定義列表中的每一行的布局來向用戶顯示更加詳細(xì)的信息。在以下兩個(gè)代碼中改進(jìn)了之前的示例,為每一行使用自定義的行布局來顯示每個(gè)條目的其他信息。
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);
//這里的取消動(dòng)作只會(huì)讓對(duì)話框消失,但在用戶單擊Cancel按鈕時(shí),
//也可以添加一個(gè)監(jiān)聽器來處理一些其他的操作
builder.setNegativeButton("Cancel", null);
mActions = builder.create();
setContentView(mButton);
}
//這里處理列表的選擇事件
@Override
public void onClick(DialogInterface dialog, int which) {
String selected = ZONES[which];
mButton.setText(selected);
}
//這里處理按鈕的單擊事件 (彈出對(duì)話框)
@Override
public void onClick(View v) {
mActions.show();
}
}
這里我們?yōu)樯善魈峁┝艘粋€(gè)ArrayAdapter,而不是簡單地傳入了選項(xiàng)數(shù)組。ArrayAdapter有g(shù)etView()的自定義實(shí)現(xiàn),會(huì)返回一個(gè)XML中自定義布局,我們現(xiàn)在可以顯示GMT偏移值和時(shí)區(qū)名稱。之后會(huì)進(jìn)一步討論自定義適配器的特性。如圖顯示了新的、更加實(shí)用的彈出式對(duì)話框。
Demo下載地址:
[2.6 顯示一個(gè)用戶對(duì)話框]
(https://download.csdn.net/download/qq_41121204/10764632)