对话框:AlertDialog
前两节我们讲到了 Toast 和 Notification,这两个属于单向的通知,也就是说只能由我们给用户传递信息,而不能接收用户的选择。当你希望在 Acitivity 内给用户传递信息的同时给用户一些选择权,并且不希望切换屏幕页面的时候,AlertDialog 将是最佳的选择。
1. AlertDialog 的特性
对话框是一个可以用来展示提示信息并支持用户输入的小弹窗
AlertDialog 可以用来让用户提交问题、做选择、确定/取消操作、向用户发送通知、错误等信息。它可以帮助我们在不跳转 Activity 的情况下轻松弹出一个悬浮窗,在本节课程中,我们会讨论如何创建各种各样常见的对话框。
2. AlertDialog 的常用 API
AlertDialog 在使用中主要以 API 为主,常用方法如下:
- setIcon(Drawable icon):
设置Alert Dialog窗口的icon
- setCancelable(boolean cancel able):
设置是否支持取消(取消通常是指点窗口外或者点“Back”)
- setTitle(CharSequence title):
设置对话框上的标题
- setMessage(CharSequence message):
设置对话框上的提示信息
- setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems, DialogInterface.OnMultiChoiceClickListener listener):
在对话框上添加多选列表,参数描述:
+ items:多选项文本数组
+ checkedItems:默认状态,true表示默认选中;false默认取消
+ listener:用户选择监听器
- setOnCancelListener(DialogInterface.OnCancelListener onCancelListener):
设置关闭监听器,在用户关闭的时候回调此接口
- setPositiveButton(CharSequence text, DialogInterface.OnClickListener listener):
设置确定监听器,在用户点击确定的时候回调此接口
- setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener):
设置取消监听器,在用户选择“取消”、“否定”等时候毁掉此接口
3. AlertDialog 的使用方法
AlertDialog 的用法和上一节的 Notification 类似,系统也提供了 Builder 建造者,通过 Builder 的create()
方法可以创建对话框,然后通过show()
方法展示,如下:
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
3.1 使用步骤
Step 1: 创建AlertDialog.Builder对象
我们也可以直接创建 AlertDialog,但这样不方便我们自定义一些功能及样式,所以更多时候还是会采用构建者模式中的 Builder 对象帮助我们去构建我们需要的 AlertDialog。
Step 2: 设置对话框的内容样式
这里主要涉及到图标icon、标题以及提示内容四个部分,对应以下 3 个接口:
- setIcon
- setTitle
- setMessage
这几个是几乎所有对话框都会用到的方法,对于一些特殊样式的 AlertDialog 还会有一些特殊接口,具体的方法我们会在下一个小节看到。
Step 3: 设置按钮
分别调用setPositiveButton()
、setNegativeButton()
、setNeutralButton()
来设置“确定”、“取消”、“中立”按钮的显示文本及点击事件回调。
Step 4: 创建 AlertDialog对象并展示
在设置完对话框的样式之后,我们直接调用 Builder 的create()
方法创建 AlertDialog 实例,最后调用 show()
方法将对话框显示出来。
3.2 普通对话框
一个普通的 AlertDialog 也是大家日常见到最多的一种,直接弹出一个提示,然后给出 1 - 3 个选项,比如“是”、“否”、“取消”等等,使用方法非常简单,基本上可以直接套用 3.1小节的步骤,代码如下:
package com.emercy.myapplication;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.alert).setOnClickListener(this);
}
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alertDialog = builder
.setIcon(R.drawable.warning)
.setTitle("系统消息:")
.setMessage("弹出一个普通的AlertDialog,\n提供确定、退出、取消三个Button")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "已确定", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "已为您取消", Toast.LENGTH_SHORT).show();
}
}).setNeutralButton("退出", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "已退出对话框", Toast.LENGTH_SHORT).show();
}
}).create(); // 通过 create() 创建AlertDialog对象
alertDialog.show(); // 通过 show() 展示对话框
}
}
然后为 Activity 编写一个布局文件,其中放置一个 Button 用于触发对话框,如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout\_width="match\_parent"
android:layout\_height="match\_parent"
android:paddingBottom="@dimen/activity\_vertical\_margin"
android:paddingLeft="@dimen/activity\_horizontal\_margin"
android:paddingRight="@dimen/activity\_horizontal\_margin"
android:paddingTop="@dimen/activity\_vertical\_margin"
tools:context="MainActivity">
<Button
android:layout\_centerInParent="true"
android:layout\_width="wrap\_content"
android:layout\_height="wrap\_content"
android:text="弹出普通 AlertDialog"
android:id="@+id/alert" />
</RelativeLayout>
编译之后点击屏幕中间的 Button,弹出来的就是一个普通对话框了。我们设置了“确定”、“取消”、“中立” 3 个Button,分别表示“确定”、“取消”以及“退出对话框” 3 种操作,实际使用中,可以在回调接口里针对 3 种 Button 设置不同的回调逻辑,效果如下:
3.3 单选对话框
单选对话框在普通对话框的基础之上增加一个用户的输入,顾名思义,我们可以给用户提供一些选项让用户勾选,然后在点击“确定”之后获取到用户的选择。
通过setSingleChoiceItems
方法设置一个字符串数组作为单选项,然后通过DialogInterface.OnClickListener
接口监听用户的选择操作。
package com.emercy.myapplication;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
final String[] hero_road = new String[] { "对抗路", "打野", "中路", "发育路", "辅助" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.alert).setOnClickListener(this);
}
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alert = builder
.setIcon(R.drawable.warning)
.setTitle("选择你要走的峡谷分路")
.setSingleChoiceItems(hero_road, 0,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(),"我要玩" + hero_road[which], Toast.LENGTH_SHORT).show();
}
}).create();
alert.show();
}
}
效果如下:
3.4 多选对话框
布局文件保持不变,只需要修改点击事件即可。通过setMultiChoiceItems()
接口设置一个多选列表,在用户选择的时候系统会回调onClick()
方法,在其中可以记录下用户的选择,代码如下:
package com.emercy.myapplication;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
final String[] hero_road = new String[] { "对抗路", "打野", "中路", "发育路", "辅助" };
private boolean[] checked = new boolean[hero_road.length];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.alert).setOnClickListener(this);
}
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alert = builder
.setIcon(R.drawable.warning)
.setTitle("选择你擅长的峡谷分路")
.setMultiChoiceItems(hero_road, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checked[which] = isChecked;
}
}).setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("“");
for (int i = 0; i < hero_road.length; i++) {
if (checked[i]) {
stringBuilder.append(hero_road[i]);
stringBuilder.append(",");
}
}
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
stringBuilder.append("”");
Toast.makeText(MainActivity.this, "我擅长" + stringBuilder, Toast.LENGTH_SHORT).show();
}
}).create();
alert.show();
}
}
效果如下:
3.5 列表对话框
使用列表对话框会弹出一个选择列表,用户可以从列表中选择一个并直接关闭对话框,设置列表采用setItems()
接口:
package com.emercy.myapplication;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
final String[] hero_road = new String[] { "对抗路", "打野", "中路", "发育路", "辅助" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.alert).setOnClickListener(this);
}
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alert = builder
.setIcon(R.drawable.warning)
.setTitle("选择你要走的峡谷分路")
.setItems(hero_road, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(),"我要走" + hero_road[which], Toast.LENGTH_SHORT).show();
}
}).create();
alert.show();
}
}
效果如图:
4. 小结
AlertDialog 相比前两节学到的 Toast 和 Notification 而言,它会直接挡住用户的界面,等待用户主动关闭,是一个比较强的通知方式。因此在使用的时候一定要慎重,不要使用的太频繁而对用户造成过度的打扰。AlertDialog 不但可以给用户通知,还能轻易的接收用户的选择,互动性比较强。它的创建方法通常是采用构建者模式,通过 AlertDialog.Builder 类来定制它的样式及内容,根据样式的不同常用的有“普通对话框”、“单选对话框”、“多选对话框”以及“列表对话框”,在设置完成之后通过create()
创建 AlertDialog,最终通过show()
完成展示。这种通过 Builder 来构建的方式在 Android 中非常常用,你学会了吗?