信息提醒之对话框(AlertDialog + ProgressDialog)-更新中
概念
Android中的对话框需要使用AlertDialog类来显示,主要用于显示提醒信息,不过这个对话框类可不仅仅能用来显示一些信息,我们可以在对话框中防止任何的控件,使其成为一个复杂且功能强大的用户接口。一个典型的例子就是使用AlertDialog做一个登录对话框。
对话框的基本用法
通过查看AlertDialog类,我们可以发现,该类并没有public的构造方法,因此我们不能直接创建AlertDialog对象。
为了创建AlertDialog对象,我们需要使用Builder类,该类是AlertDialog的内部类。
首先,必须创建AlertDialog.Builder对象
然后,通过Builder的show方法显示对话框
或者通过Builder.create方法返回AlertDialog对象,再通过AlertDiaolg.show方法显示对话框。
带2个按钮(确认、取消)的对话框
显示这样的对话框的关键是如何显示两个按钮以及响应这两个按钮的单击事件。 通过AlertDialog.setPostitiveButton和AlertDialog.setNegativeButton可以为对话框添加两个按钮。
我们来看下这两个方法的定义
public Builder setPositiveButton(CharSequence text, final OnClickListener listener)public Builder setPositiveButton(@StringRes int textId, final OnClickListener listener)public Builder setNegativeButton(CharSequence text, final OnClickListener listener) public Builder setNegativeButton(@StringRes int textId, final OnClickListener listener)从上述的源码中可以看出,setPositiveButton和setNegativeButton方法各有两个重载形式,实现的功能是一致的,区别在于 text参数可以直接指定文本或者String变量,textId参数则需要指定一个字符串资源ID(需要在res\values目录中的xml文件中定义)。
一般来讲,setPositiveButton的按钮来添加 “确定”“Yes”等按钮,setNegativeButton方法来添加“取消”,”cancel”等。
OnClickListener为DialogInterface.OnClickListener中的类。响应用户的操作。
在使用AlertDialog类来创建对话框时需要注意以下几点:
- setPositvieButton和setNegativeButton方法的第二个参数的数据类型是android.content,DialogInterface.OnClickListener,而不是android.view.View.OnClickListener. View.OnClickListener接口使用在视图上的,这一点在使用时要注意。
- 使用show()方法显示对话框是异步的,也就是说,当调用AlertDialog.Builder.show 或者AlertDialog.show方法显示对话框后,show方法会立即返回,并且继续执行后面的代码。
- 单击使用setPositiveButton和setNegativeButton方法添加的按钮后,即使单击事件中不写任何代码,对话框也是会关闭的
- 如果某个按钮单击后只需要关闭对话框,并不需要进行任何处理,listener参数设置null即可
- AlertDialog类还有很多setXXX方法用于指定对话框的其他资源,可以是对话框更加丰满美观。
带3个按钮(覆盖、忽略、取消)的对话框
用AlertDialog类创建的对话框最多可以添加3个按钮,除了上面添加两个方法,还可以使用setNeutralButton方法向对话框中添加第三个按钮
注意事项:
- setPositiveButton setNegativeButton setNeutralButton的调用顺序可以是任意的,但是无论调用顺序是什么,在2.3这些低版本中,setPositiveButton 总会在左起第一个 ,setNeutralButton位于左起第二个,setNegativeButton位于左起第三个。 在高版本中,Googel调整了显示位置,setPositiveButton位于右起第一位,setNeutralButton位于右起第二个,setNegativeButton位于右起第三位。
- 使用AlertDialog类创建的对话框最多只能有3个按钮,因此,就算多次调用这3个设置按钮的方法,最多也只能显示3个。
- 这3个设置对话框按钮的方法虽然可以调用多次,但是系统只以每一个方法最后一次调用的为准。
简单列表对话框-setItems
通过AlertDialog.Builder类的setItems方法可以创建简单的列表对话框。 实际上,这种对话框相当于将ListView控件放在对话框上,然后在ListView中添加若干简单的文本()。
在这个实例中,选择后显示选中值,5S后自动关闭。
setItems方法定义如下
// items表示用于显示在列表中的字符串数组 public Builder setItems(CharSequence[] items, final OnClickListener listener) // items标识字符串数据的资源ID public Builder setItems(@ArrayRes int itemsId, final OnClickListener listener)第二个参数 为 DialogInterface.OnClickListener类型。
new AlertDialog.Builder(this).setIcon(R.drawable.flag_mark_gray).setTitle("请选择省份").setItems(proviences, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 选择后的提示信息 记得调用show方法,否则不显示啦final AlertDialog alertDialog = new AlertDialog.Builder(DialogDemoListAct.this).setMessage("选择了" + proviences[which]).show();// 设置定时器,5秒后,关闭AlertDialogHandler handler = new Handler();handler.postDelayed(new Runnable() {@Overridepublic void run() { // alertDialog.cancel(); 也可以alertDialog.dismiss();}}, 5 * 1000);}}).show();在DialogInterface接口中有两个用于关闭对话框的方法:dismiss 和 cancel,这两个方法的功能完全相同,都是关闭对话框。
单选列表对话框-setSingleChoiceItems
通过AlertDialog.Builder类的setSingleChoiceItems方法可以创建带有单选按钮的列表对话框。setSingleChoiceItems有4个重载形式:
// 从字符串数组中装载数据 public Builder setSingleChoiceItems(CharSequence[] items, int checkedItem, final OnClickListener listener) // 从资源文件中装载数据 public Builder setSingleChoiceItems(@ArrayRes int itemsId, int checkedItem,final OnClickListener listener) // 从ListAdapter中装载数据 public Builder setSingleChoiceItems(ListAdapter adapter, int checkedItem, final OnClickListener listener) // 从数据集中装载数据 public Builder setSingleChoiceItems(Cursor cursor, int checkedItem, String labelColumn,final OnClickListener listener)参数解释:
- 第一个参数:表示单选列表对话框的数据源,目前支持4种数据源,分别是 数据资源、数据集、字符串数组和ListAdapter对象
- checkedItem:表示默认选中的列表项。如果设置第一个列表项为选中状态,该参数值为0 。 如果该值小于0,表示所有的列表项都未被选中。
- listener: 单击某个列表项被触发的事件对象
- lableColumn:如果数据源是数据集Cursor,数据集中的某一列作为列表对话框的数据加载到列表控件中。该参数表示该列的名称(字段名)
多选列表对话框-setMultiChoiceItems
通过AlertDialog.Builder.setMultiChoiceItems方法可以创建带复选框的列表对话框。
setMultiChoiceItems有3个重载方法
// 从资源文件中装载数据 public Builder setMultiChoiceItems(@ArrayRes int itemsId, boolean[] checkedItems,final OnMultiChoiceClickListener listener) // 从字符串数组中装载数据 public Builder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,final OnMultiChoiceClickListener listener) // 从数据集中装载数据 public Builder setMultiChoiceItems(Cursor cursor, String isCheckedColumn, String labelColumn,final OnMultiChoiceClickListener listener)参数解释:
- 第一个参数表示多选列表对话框的数据源,目前支持3种数据源:数组资源、数据集和字符串数组
- checkedItems:该参数的数据类型为boolean[],这个参数值的长度要和列表框中的列表项个数相同,该参数用于设置每一个列表项的默认值,默认为true,表示当前的列表项是选中状态,否则表示未选中状态
- listener:表示选中某一哥列表项时被触发的事件对象
- isCheckedColumn:该参数只用于数据集Cursor数据源,用于指定数据集的一列(字段名);如果为0,则未被选中。也就是说,对于数据集来说,某个列表项是否被选中,是有另外一列的字段值决定的。
- labelColumn:只用于数据集。指定用于显示列表项的列的字段名。
注意事项:
- 必须指定setMulitChoiceItems方法的单击事件对象,也就是改方法的第三个参数,该参数不能设置为null,否则默认被选中的列表项无法置成未选中状态。对于默认未被选中的列表项没有任何影响。
- 由于存在“确定”按钮的单击事件中需要引用AlertDialog变量,因此先使用create方法返回AlertDialog对象,然后在单击事件中使用该变量
进度对话框
查看大拿的总结
进度对话框通过android.app.ProgressDialog类实现,该类是AlertDialog的之类,但与AlertDialog类不同,我们可以直接使用new关键字创建ProgressDialog对象。
进度条对话框除了要设置普通对话框必要的值外,还需要设置另外两个值:进度的最大值和当前的进度。
// 设置进度的最大值 public void setMax(int max) // 设置当前的进度 public void setProgress(int value)初始进度必须使用setProgress方法设置,而递增进度除了可以使用setProgress方法设置外,还可以使用以下方法
// 设置进度值的增量 public void incrementProgressBy(int diff)区别在于 setProgress设置的绝对值,incrementProgressBy设置的是进度的增量。
与普通的对话框一样,进度对话框最多也只能添加3个按钮,而且可以设置进度对话框的风格:
// 创建ProgressDialog类 ProgressDialog pg = new ProgressDialog(); // 设置进度对话框为水平进度条风格 pg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);案例说明:
本案例演示了水平和原型进度对话框的实现方法,其中进度条包含两个按钮“暂停”和 “停止”,单击暂停后,进度对话框关闭,再此显示进度对话框时,进度条的起始位置从上次关闭对话框的位置开始(仅限与水平进度条)。 单击取消,关闭对话框,再此显示时,进度从0开始。
要实现进度随着时间的变化而不断递增,需要使用多线程及定时器来完成这个工作, 本例中使用Handler类来不断更新进度对话框的进度值。
注意事项:
- 进度对话框默认是圆形进度条,如需要设置水平进度条,使用setProgressStyle方法进行设置
- 调用sendEmptyMessage方法只能是handleMessage方法执行一次,要想以一定的时间间隔循环执行handleMessage方法,需要在handleMessage方法中调用sendEmptyMessageDelayed方法来设置hanleMessage方法下一次被调用的等待时间,这样就可以形成一个循环调用的效果。
- sendEmptyMessage和 sendEmptyMessageDelayed方法的第一个参数表示消息代码,这个消息代码用来标识消息队列中的消息。 例如,使用sendMessageDelayed方法设置消息代码为1的消息在(50+)毫秒后调用handleMessage方法,可以利用这个消息代码删除该消息,这样系统就不会在(50+)毫秒之后调用handleMessage方法了。 在本例中,暂停和取消按钮单击事件都使用removeMessages方法删除了消息代码为1的消息。
- 消息代码可以是任意int类型的值
- 虽然ProgressDialog.getProgress可以获取当前进度,但是只有在水平进度条风格的对话框中才有效,如果是圆形进度条,该方法返回永远是0 。 因此本案例单独使用了一个progress变量来代替当前进度,当进度条风格是圆形时,就意味着对话框永远不会被关闭。
- 圆形进度条对话框的进度圆圈只是一个普通的动画,并没有任何表示进度的功能,这种对话框一般在很难估计准确的时间和进度时使用
登录对话框,自定义布局 -setView
我们可以直接使用布局文件或者代码创建视图对象,并将这些属兔对象添加到对话框中。
AlertDialog.Builder.setView方法可以将视图对象添加到当前的对话框中,使用下面的形式将一个视图对象添加到对话框中。
new AlertDialog.Builder(this).setIcon(R.drawable.xxx).setTitle("自定义对话框").setView(......).show();
主要代码:
activity_alertdialog_login.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><LinearLayout android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:orientation="horizontal" ><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="用户名:"android:textSize="20sp" /><EditText android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"/></LinearLayout><LinearLayout android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:orientation="horizontal" ><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="密 码:"android:textSize="20sp" /><EditText android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:password="true" /></LinearLayout></LinearLayout>使用Activity托管对话框
Activity类提供了创建对话框的快捷方式。 在Activity类中有一个onCreateDialog方法。定义如下
protected Dialog onCreateDialog(int id)当调用Activity.showDialog方法时,系统会调用onCreateDialog方法来返回一个Dialog对象 (AlertDialog是Dialog的子类)。 showDialog方法和onCreateDialog方法一样,也有一个int类型的id参数。该参数值传入onCreateDialog方法。可以利用不同的id来建立多个对话框。
import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ListView;import com.turing.base.R;public class ActivityDialog extends Activity implements View.OnClickListener {private final int DIALOG_DELETE_FILE = 1;private final int DIALOG_SIMPLE_LIST = 2;private final int DIALOG_SINGLE_CHOICE_LIST = 3;private final int DIALOG_MULTI_CHOICE_LIST = 4;private ListView lv = null;private String[] provinces = new String[]{"辽宁省", "山东省", "河北省", "福建省", "广东省", "黑龙江省"};private ButtonOnClick buttonOnClick = new ButtonOnClick(1);@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.btnDeleteFile:showDialog(DIALOG_DELETE_FILE);break;case R.id.btnSimpleList:showDialog(DIALOG_SIMPLE_LIST);break;case R.id.btnSingleChoiceList:showDialog(DIALOG_SINGLE_CHOICE_LIST);break;case R.id.btnMultiChoiceList:showDialog(DIALOG_MULTI_CHOICE_LIST);break;case R.id.btnRemoveDialog:removeDialog(DIALOG_DELETE_FILE);removeDialog(DIALOG_SIMPLE_LIST);removeDialog(DIALOG_SINGLE_CHOICE_LIST);removeDialog(DIALOG_MULTI_CHOICE_LIST);break;}}@Overrideprotected Dialog onCreateDialog(int id) {Log.d("dialog", String.valueOf(id));switch (id) {case DIALOG_DELETE_FILE:return new AlertDialog.Builder(this).setIcon(R.drawable.flag_mark_gray).setTitle("是否删除文件").setPositiveButton("确定",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int whichButton) {new AlertDialog.Builder(ActivityDialog.this).setMessage("文件已经被删除.").create().show();}}).setNegativeButton("取消",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int whichButton) {new AlertDialog.Builder(ActivityDialog.this).setMessage("您已经选择了取消按钮,该文件未被删除.").create().show();}}).create();case DIALOG_SIMPLE_LIST:return new AlertDialog.Builder(this).setTitle("选择省份").setItems(provinces, new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int which) {final AlertDialog ad = new AlertDialog.Builder(ActivityDialog.this).setMessage("您已经选择了: " + which + ":"+ provinces[which]).show();android.os.Handler hander = new android.os.Handler();hander.postDelayed(new Runnable() {@Overridepublic void run() {ad.dismiss();}}, 5 * 1000);}}).create();case DIALOG_SINGLE_CHOICE_LIST:return new AlertDialog.Builder(this).setTitle("选择省份").setSingleChoiceItems(provinces, 1, buttonOnClick).setPositiveButton("确定", buttonOnClick).setNegativeButton("取消", buttonOnClick).create();case DIALOG_MULTI_CHOICE_LIST:AlertDialog ad = new AlertDialog.Builder(this).setIcon(R.drawable.flag_mark_blue).setTitle("选择省份").setMultiChoiceItems(provinces, new boolean[]{false, true, false, true, false, false},new DialogInterface.OnMultiChoiceClickListener() {public void onClick(DialogInterface dialog,int whichButton, boolean isChecked) {}}).setPositiveButton("确定",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int whichButton) {int count = lv.getCount();String s = "您选择了:";for (int i = 0; i < provinces.length; i++) {if (lv.getCheckedItemPositions().get(i))s += i + ":"+ lv.getAdapter().getItem(i)+ " ";}if (lv.getCheckedItemPositions().size() > 0) {new AlertDialog.Builder(ActivityDialog.this).setMessage(s).show();} else {new AlertDialog.Builder(ActivityDialog.this).setMessage("您未选择任何省份").show();}}}).setNegativeButton("取消", null).create();lv = ad.getListView();return ad;}return null;}private class ButtonOnClick implements DialogInterface.OnClickListener {private int index;public ButtonOnClick(int index) {this.index = index;}@Overridepublic void onClick(DialogInterface dialog, int whichButton) {if (whichButton >= 0) {index = whichButton;} else {if (whichButton == DialogInterface.BUTTON_POSITIVE) {new AlertDialog.Builder(ActivityDialog.this).setMessage("您已经选择了: " + index + ":" + provinces[index]).show();} else if (whichButton == DialogInterface.BUTTON_NEGATIVE) {new AlertDialog.Builder(ActivityDialog.this).setMessage("您什么都未选择.").show();}}}}@Overrideprotected void onPrepareDialog(int id, Dialog dialog) {super.onPrepareDialog(id, dialog);}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_activity_dialog);Button btnDeleteFile = (Button) findViewById(R.id.btnDeleteFile);Button btnSimpleList = (Button) findViewById(R.id.btnSimpleList);Button btnSingleChoiceList = (Button) findViewById(R.id.btnSingleChoiceList);Button btnMultiChoiceList = (Button) findViewById(R.id.btnMultiChoiceList);Button btnRemoveDialog = (Button) findViewById(R.id.btnRemoveDialog);btnDeleteFile.setOnClickListener(this);btnSimpleList.setOnClickListener(this);btnSingleChoiceList.setOnClickListener(this);btnMultiChoiceList.setOnClickListener(this);btnRemoveDialog.setOnClickListener(this);} }对话框的高级应用
改变对话框的显示位置
默认对话框的位置都是位于屏幕的中央,其实可以根据需要位于屏幕的上下左右甚至是任意位置,
要控制对话框的显示位置,需要获得对话框的Window对象,并通过Window对象的一些方法来控制对话框的显示位置。
case 12: // 改变对话框的显示位置 // changePostionOfDialog(Gravity.TOP); // changePostionOfDialog(Gravity.BOTTOM); // changePostionOfDialog(Gravity.LEFT); // changePostionOfDialog(Gravity.RIGHT);// 右上方 // changePostionOfDialog(Gravity.RIGHT | Gravity.TOP);// 显示在任意位置showAnyPostionOfDilaog();break; private void changePostionOfDialog(int postion) {/**AlertDialog alertDialog = new AlertDialog.Builder(this).setIcon(R.drawable.flag_mark_blue).setTitle("改变位置的AlertDiaolog").setMessage("我在" + postion).create();alertDialog.getWindow().setGravity(postion);alertDialog.show();**/ProgressDialog progressDialog = new ProgressDialog(this);progressDialog.setIcon(R.drawable.flag_mark_yellow);progressDialog.setTitle("ProgressDialog改变位置");progressDialog.setMessage("where am I ?");progressDialog.getWindow().setGravity(postion);progressDialog.show();} private void showAnyPostionOfDilaog() {AlertDialog ad = new AlertDialog.Builder(this).setIcon(R.drawable.flag_mark_blue).setTitle("改变位置的AlertDiaolog").setMessage("我在自定义的任意位置").create();Window window = ad.getWindow();WindowManager.LayoutParams lp = window.getAttributes();// 设置水平偏移量lp.x = -20;// 设置垂直偏移量lp.y = -120;window.setAttributes(lp);ad.show();}在对话框按钮和内容文本中插入图像
给TextView控件中插入图像的方法同样也适用。
AlertDialog alertDialog = new AlertDialog.Builder(this).setIcon(R.drawable.flag_mark_blue).setTitle("问候").setMessage(Html.fromHtml("哈哈,<img src=''/>你好.", new Html.ImageGetter() {@Overridepublic Drawable getDrawable(String source) {Drawable drawable = getResources().getDrawable(R.drawable.face);drawable.setBounds(0, 0, 32, 32);return drawable;}}, null)).setPositiveButton(Html.fromHtml("<img src=''/>确定", new Html.ImageGetter() {@Overridepublic Drawable getDrawable(String source) {Drawable drawable = getResources().getDrawable(R.drawable.ok);drawable.setBounds(0, 0, 20, 20);return drawable;}}, null), null).setNegativeButton(Html.fromHtml("<img src=''/>取消", new Html.ImageGetter() {@Overridepublic Drawable getDrawable(String source) {Drawable drawable = getResources().getDrawable(R.drawable.cancel);drawable.setBounds(0, 0, 20, 20);return drawable;}}, null), null).create();alertDialog.show();改变对话框的透明度
通过WindowManager.LayoutParams.alpha可以设置对话框的透明度。
Alpha的取值范围为0.0f ~ 1.0f之间,f表示float类型的数字。 默认1.0f ,完全不透明。 0.0f表示全透明,此时就看不到对话框了。
0.7f
private void showTransparency_dialog(float v) {// 创建对话框AlertDialog ad = new AlertDialog.Builder(this).setTitle("改变对话框的透明度").setIcon(R.drawable.tag_red).setMessage("Alpha的取值范围 0~1 ,默认 1 ,我的透明度是" + v).setPositiveButton("确定",null).create();// 设置透明度Window window = ad.getWindow();WindowManager.LayoutParams lp = window.getAttributes();lp.alpha = v ;window.setAttributes(lp);// 展示对话框ad.show();}总结
以上是生活随笔为你收集整理的信息提醒之对话框(AlertDialog + ProgressDialog)-更新中的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 信息提醒之Toast-更新中
- 下一篇: 信息提醒之Notification,兼容