在应用程序中有些时候,如果想询问用户采取决定是或否所采取的特殊动作的回应,由停在原来的活动而不改变屏幕,可以使用警告对话框(Alert Dialog)。
AlertDialog继承自Dialog类,对于Android内置的AlertDialog,它可以包含一个标题、一个内容消息或者一个选择列表、最多三个按钮。
而创建AlertDialog推荐使用它的一个内部类AlterDialog.Builder创建。
它的语法如下面给出:
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(Context context);
使用Builder对象,可以设置AlertDialog的各种属性来自定义警告对话框,最后通过Builder.create()就可以得到AlertDialog对 象,如果只是还需要显示这个AlertDialog,一般可以直接使用Builder.show()方法,它会返回一个AlertDialog对象,并且显示它。
下表列出了自定义警告对话框的常用方法:
AlterDialog内置了三个按钮,可以直接使用setXxxButton()方法进行设置,对于一般的对话框,使用三个按钮基本上也够用了,下面是这三个方法的签名:
AlterDialog.Builder setPositiveButton(CharSquence text , DialogInterface.OnClickListener listener):一个积极的按钮,一般用于“OK”或者“继续”等操作。
AlterDialog.Builder setNegativeButton(CharSquence text , DialogInterFace.OnClickListener listener):一个负面的按钮,一般用于“取消”操作。
AlterDialog.Builder setNeutralButton(CharSquence text , DialogInterFace.OnClickListener listener):一个比较中性的按钮,一般用于“忽略”、“以后提醒我”等操作。
普通的AlertDialog
例子:
下面例子演示如何使用AlertDialog,该警告对话框带图标、标题、信息和三个按钮:
public class MainActivity extends AppCompatActivity {
private Button normalDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
normalDialog = (Button)this.findViewById(R.id.normalDialog);
normalDialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("提示");
builder.setMessage("确认更新吗?");
builder.setIcon(R.mipmap.ic_launcher);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "确定",
Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "取消",
Toast.LENGTH_SHORT).show();
}
});
builder.setNeutralButton("以后提醒我", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "以后提醒我",
Toast.LENGTH_SHORT).show();
}
});
builder.show();
}
});
}
}
效果展示:
带列表的AlertDialog
如果需要给用户提供的选择比较多,就不要使用按钮了,按钮过多对话框会很不好看,我们可以设置一个列表,在列表中列出所有提供的选项。比如我们长按某个文件就会弹出一些列表,打开、添加或是删除操作。
private void listDialog() {
//定义列表中的内容
final String[] items = {"打开","添加","删除"};
//先new出一个监听器,设置好监听
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
//这个which实际上代表的是一个唯一的int型数值
if(which==0){
Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
else if(which == 1){
Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("提示");
builder.setIcon(R.mipmap.ic_launcher);
builder.setItems(items,listener);
builder.setNegativeButton("取消",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
效果展示:
注意:
列表对话框只需设置Items属性即可,注意不能在设置Message属性,否则只会显示Message,不会显示列表。这里的setItems中的Onclick中的which属性是items数组的下标!
还有另外一种实现带列表的对话框的方式,自定义列表项对话框:
private void viewDialog() {
final String[] items = {"北京","上海","广州","深圳"};
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("请选择城市");
builder.setIcon(R.mipmap.city);
builder.setAdapter(new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,items),listener);
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
调用 builder.setAdapter()方法将自定义列表设置到对话框。
下面是效果展示:
带单选列表的AlertDialog
有的时候我们需要弹出一个带单选列表的警告对话框,给用户提供多个选项,但只允许选择一个。
final String[] items = {"音乐","舞蹈","美术"};
final int mWhich = 0;
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog,int which) {
Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("请选择爱好");
builder.setSingleChoiceItems(items,mWhich,listener);
builder.setPositiveButton("确定",new AlertDialog.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
设置单选列表对话框使用setSingleChoiceItems (CharSequence[] items, int checkedItem, DialogInterface.OnClickListener listener)方法,第一个参数是一个字符串数组,第二个参数表示当前选中列表第几项(从0开始),第三个参数是监听器;
下面看运行效果:
带多选列表的对话框
还有一个多选对话框,给用户提供多个选项,并且可以同时选择多个。
private void multiDialog() {
//定义多选的选项
final String[] items = {"AK47","RPK","97式","猎魔双鱼"};
//使用一个boolean数组表示默认选中项,因为是多选,可以有多个默认选中项,哪项被选中就把值赋为true
boolean[] selected = {true,false,true,false};
DialogInterface.OnMultiChoiceClickListener listener = new DialogInterface.OnMultiChoiceClickListener(){
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
//点击某个选项,就改变该选项对应的boolean值,记录其是否被选中
Toast.makeText(MainActivity.this, items[which]+isChecked, Toast.LENGTH_SHORT).show();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("请选择武器");
builder.setIcon(R.mipmap.ic_launcher);
builder.setMultiChoiceItems(items,selected,listener);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
多选列表对话框使用setMultiChoiceItems (CharSequence[] items, boolean[] checkedItems, DialogInterface.OnMultiChoiceClickListener listener)方法来设置对话框的Content Area。同样,该方法第一个参数是一个字符串数组;第二个参数是一个布尔数组,用来记录默认选项,null表示没有默认项;第三个参数是一个监听器。
程序运行效果如下所示:
自定义View的对话框
有的时候单选、多选、列表都不能满足我们的需求,这时我们可以自定义对话框的布局。使用AlertDialog.Builder类的setView方法,默认情况下,我们定义的布局将会充满整个对话框窗口。
首先是布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/grid_selector_background_pressed"/>
<EditText
android:id="@+id/editName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="50dp"
android:hint="UserName"/>
<EditText
android:id="@+id/editWord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:inputType="textPassword"
android:hint="PassWord" />
</LinearLayout>
布局文件就是一个简单的登录界面,两个EditText输入用户名和密码。注意LinearLayout里的drawable图片文件,是.9.png的图片格式,直接放进来会出错,解决办法参考前面写过的文章。
下面是对话框代码:
private void createDialog() {
View myView;
//使用LayoutInflater加载布局文件
LayoutInflater factory = LayoutInflater.from(MainActivity.this);
myView = factory.inflate(R.layout.create_dialog,null);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
//设置自定义布局
builder.setView(myView);
builder.setPositiveButton("登录",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).setNegativeButton("取消",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
首先使用LayoutInflater.from()获得LayoutInflater对象,然后利用LayoutInflater对象将布局文件解析成View对象,最后调用 builder.setView()方法将自定义布局设置到对话框。
下面看程序运行效果:
带对话框的对话框
上面我们所实现的带列表的AlertDialog,某些情况下,我们需要点击其中某项弹出另一个AlertDialog。
private void listDialog() {
final View myView;
LayoutInflater factory = LayoutInflater.from(MainActivity.this);
myView = factory.inflate(R.layout.rename_dialog,null);
EditText editText = (EditText)myView.findViewById(R.id.editText);
final String[] items = {"打开","添加","删除"};
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if(which==0){
Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
else if(which == 1){
DialogInterface.OnClickListener listener1 = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this,"确定",Toast.LENGTH_SHORT).show();
}
};
AlertDialog renameDialog = new AlertDialog.Builder(MainActivity.this).create();
renameDialog.setView(myView);
renameDialog.setButton(DialogInterface.BUTTON_POSITIVE,"确定",listener1);
renameDialog.setButton(DialogInterface.BUTTON_NEGATIVE,"取消",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
renameDialog.show();
// Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
}
};
这里我假设点击“添加”,弹出一个对话框,那么我们就在which=1的情况下,再为它设置一个监听器,注意:这种情况下,只能用如下语句AlertDialog renameDialog = new AlertDialog.Builder(MainActivity.this).create();
来生成对话框,要调用create()方法,最后也必须用builder.show()
的方式来显示对话框。
下面是效果展示:
带icon列表项的对话框
这个对话框算是自定义列表项对话框的扩展,你可以自己定义列表项:
先看列表项布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:src="@mipmap/city" />
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:textSize="18sp"
android:textColor="@color/colorPrimary"
android:text="xiaoguo" />
</LinearLayout>
接下来看对话框部分的代码:
private void iconDialog() {
final String[] items = {"淘宝","百度","腾讯","网易云"};
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this,items[which],Toast.LENGTH_SHORT).show();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("请选择公司");
builder.setAdapter(new MyAdapter(MainActivity.this,items),listener);
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.show();
}
首先使用LayoutInflater.from()获得LayoutInflater对象,然后利用LayoutInflater对象加载布局文件,最后调用 builder.setAdapter()方法将我们自定义的adapter设置到对话框。
最后是自定义的adapter代码:
public class MyAdapter extends BaseAdapter{
private Context mContext;
private String[] items;
private LayoutInflater mInflater;
public MyAdapter(Context context, String[] arrs) {
mInflater = LayoutInflater.from(context);
mContext = context;
items = arrs;
}
@Override
public int getCount() {
return items.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
convertView = mInflater.inflate(R.layout.list_item,null);
holder = new ViewHolder();
holder.txtView = (TextView)convertView.findViewById(R.id.txt);
holder.image = (ImageView)convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
else{
holder = (ViewHolder)convertView.getTag();
}
if(0 == position){
holder.txtView.setText(items[0]);
holder.image.setImageResource(R.mipmap.taobao);
}
if(1 == position){
holder.txtView.setText(items[1]);
holder.image.setImageResource(R.mipmap.baidu);
}
if(2 == position){
holder.txtView.setText(items[2]);
holder.image.setImageResource(R.mipmap.tengxun);
}
if(3 == position){
holder.txtView.setText(items[3]);
holder.image.setImageResource(R.mipmap.wangyiyun);
}
return convertView;
}
private class ViewHolder {
TextView txtView;
ImageView image;
}
}
下面是效果展示: