前两节我们讲到了 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 中非常常用,你学会了吗?