Android Dialog详解

山居秋暝

[唐] 王维
空山新雨后,天气晚来秋。
明月松间照,清泉石上流。
竹喧归浣女,莲动下渔舟。


【韵译】
一场新雨过后,青山特别清朗,
秋天的傍晚,天气格外的凉爽。
明月透过松林撒落斑驳的静影,
清泉轻轻地在大石上叮咚流淌。
竹林传出归家洗衣女的谈笑声,
莲蓬移动了,渔舟正下水撒网。
任凭春天的芳菲随时令消逝吧,
游子在秋色中,自可留连徜徉


在Android开发过程中我们经常会遇到如下的场景: 在界面上弹出一个弹框,对用户进行提醒,并让用户做出某些选择性的操作  

           Android Dialog详解                                                                   Android Dialog详解

        删除某个应用的系统级别的Dialog                                                                       某个应用的Dialog


上面是两个比较常用的场景,还有很多场景可用到Dialog. 那么我们就来开始学习Dialog吧.

Andoid系统给我们提供了8种定义好的Dialog.拿过来就可以直接使用. 但是这7种Dialog可能跟我们 app风格不符,甚至有些丑陋,那么我们就需要自定义Dialog

在学习自定义Dialog之前我们先学习下Android给我们提供的几种现成的Dialog


一.普通的Dialog

Android Dialog详解

效果图


代码实现

package com.example.administrator.day_20;


import android.app.Dialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //构建Dialog建造者                                   //上下文环境
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        //设置标题
        builder.setTitle("对话框");
        //设置图标
        builder.setIcon(R.mipmap.ic_launcher);
        //设置Message
        builder.setMessage("哈哈哈哈");


        //设置确定按钮及其点击事件
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是确定按钮");
            }
        });
        //设置取消按钮及其点击事件
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是取消按钮");
            }
        });
        //设置中立按钮及其点击事件
        builder.setNeutralButton("中立", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是中立按钮");
            }
        });
        //使用Dialog构造器,创造出来一个Dialog
        Dialog dialog = builder.create();
        //显示
        dialog.show();
    }
}


二   列表形式的Dialog

Android Dialog详解


代码实现

package com.example.administrator.day_20;


import android.app.Dialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //构建Dialog建造者                                   //上下文环境
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        //设置标题
        builder.setTitle("对话框");
        //设置图标
        builder.setIcon(R.mipmap.ic_launcher);
//        //设置Message,如果用列表形式的Dialog这行代码需要去掉
//        builder.setMessage("哈哈哈哈");


        final String[] items = {"111","222","333","444"};
        //设置确定按钮及其点击事件
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是确定按钮");
            }
        });
        //设置取消按钮及其点击事件
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是取消按钮");
            }
        });
        //设置中立按钮及其点击事件
        builder.setNeutralButton("中立", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是中立按钮");
            }
        });
        //相对于普通Dialog改变的地方
        builder.setItems(items, new DialogInterface.OnClickListener() {
            //which表示点击的是items中的第几个
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha",items[which]);
            }
        });
        //使用Dialog构造器,创造出来一个Dialog
        Dialog dialog = builder.create();
        //显示
        dialog.show();
    }
}

三  适配器Dialog

Android Dialog详解


代码实现

package com.example.administrator.day_20;


import android.app.Dialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //构建Dialog建造者                                   //上下文环境
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        //设置标题
        builder.setTitle("对话框");
        //设置图标
        builder.setIcon(R.mipmap.ic_launcher);
    //跟普通Dialog不一样的地方
        final String[] items = {"111","222","333","444"};
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,R.layout.support_simple_spinner_dropdown_item,items);


        builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha",items[which]);
            }
        });


        //设置确定按钮及其点击事件
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是确定按钮");
            }
        });
        //设置取消按钮及其点击事件
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是取消按钮");
            }
        });
        //设置中立按钮及其点击事件
        builder.setNeutralButton("中立", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是中立按钮");
            }
        });


        //使用Dialog构造器,创造出来一个Dialog
        Dialog dialog = builder.create();
        //显示
        dialog.show();
    }
}


四   单选Dialog

Android Dialog详解


代码实现

package com.example.administrator.day_20;


import android.app.Dialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //构建Dialog建造者                                   //上下文环境
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        //设置标题
        builder.setTitle("对话框");
        //设置图标
        builder.setIcon(R.mipmap.ic_launcher);


        final String[] items = {"111","222","333","444"};


        //参数二表示默认选中哪一项   参数三表示最终点击的是第几项
        builder.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha",items[which]);
            }
        });


        //设置确定按钮及其点击事件
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是确定按钮");
            }
        });
        //设置取消按钮及其点击事件
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是取消按钮");
            }
        });
        //设置中立按钮及其点击事件
        builder.setNeutralButton("中立", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是中立按钮");
            }
        });


        //使用Dialog构造器,创造出来一个Dialog
        Dialog dialog = builder.create();
        //显示
        dialog.show();
    }
}

五  多选Dialog

Android Dialog详解


代码实现

package com.example.administrator.day_20;


import android.app.Dialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //构建Dialog建造者                                   //上下文环境
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        //设置标题
        builder.setTitle("对话框");
        //设置图标
        builder.setIcon(R.mipmap.ic_launcher);


        final String[] items = {"111","222","333","444"};
        //跟items中的数据一一对应,为true表示默认选中
        final boolean[] selected = {true,false,true,false};


        builder.setMultiChoiceItems(items, selected, new DialogInterface.OnMultiChoiceClickListener() {
            //which表示哪个被点击了   isChecked表示选中了还是取消了
            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                Log.i("haha",items[which]);
                selected[which] = isChecked;
            }
        });



        //设置确定按钮及其点击事件
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是确定按钮");
            }
        });
        //设置取消按钮及其点击事件
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是取消按钮");
            }
        });
        //设置中立按钮及其点击事件
        builder.setNeutralButton("中立", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.i("haha","我是中立按钮");
            }
        });


        //使用Dialog构造器,创造出来一个Dialog
        Dialog dialog = builder.create();
        //显示
        dialog.show();
    }
}


六  时间选择Dialog


Android Dialog详解


代码实现

package com.example.administrator.day_20;


import android.app.TimePickerDialog;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TimePicker;


import java.util.Calendar;


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    //获取当前时间 
        final int hour = Calendar.getInstance().get(Calendar.HOUR);
        int minute = Calendar.getInstance().get(Calendar.MINUTE);
    
        TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                Log.i("haha",hourOfDay +"/"+minute);
            }
        },hour,minute,true);


        timePickerDialog.show();
    }
}

七  日期选择的Dialog

Android Dialog详解


代码实现



package com.example.administrator.day_20;


import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.DatePicker;
import android.widget.TimePicker;


import java.util.Calendar;


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        //因为底层月份是从0开始的所以真是的月份我们需要减一
        int month = calendar.get(Calendar.MONTH) - 1;
        final int day = calendar.get(Calendar.DAY_OF_MONTH);


        DatePickerDialog datePickerDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                Log.i("haha",year+"/" + month + "/" + day);
            }
        },year,month,day);


        datePickerDialog.show();
    }
}


八   进度Dialog


Android Dialog详解

package com.example.administrator.day_20;


import android.app.ProgressDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ProgressBar;




public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ProgressDialog pb = new ProgressDialog(this);
        //设置标题
        pb.setTitle("进度条Dialog");
        //设置图标
        pb.setIcon(R.mipmap.ic_launcher);
        //设置信息
        pb.setMessage("拼命加载中");
        //进度条的最大值
        pb.setProgress(100);
        //设置进度条为水平style
        pb.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        //设置二级进度(看视频时候的缓冲进度)的初始值
        pb.setSecondaryProgress(20);
        pb.show();
    }
}


以上就是系统给我们提供的Dialog,看上去不是很美观,也不太能适应现在主流app的风格,那就需要我们去自定义Dialog,接下来我们就开始自定义吧!!!


九  自定义Dialog


Android Dialog详解


代码实现


步骤1.给自定义的Dialog自定义一个style,现在主流 app的Dialog都使用全透明无边框风格,那我们也要紧跟时代潮流!!

( 在res/values/styles中加入自定义的style)

    <resources>
    //通过MyDialog这个名字来引用这个文件
    <style name="MyDialog" parent="android:Theme.Dialog">
        //背景设置成透明
        <item name="android:windowBackground">@android:color/transparent</item>
        //去除标题
        <item name="android:windowNoTitle">true</item>
        //去除边框
        <item name="android:windowFrame">null</item>
        //是否悬浮在Activity之上
        <item name="android:windowIsFloating">true</item>
        //是否背景模糊
        <item name="android:backgroundDimEnabled">true</item>
    </style>

</resources>


步骤2.给自定义的Dialog自定义一个布局文件(在res/layout/my_dialog.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="match_parent"
    android:background="#11ffffff">
    <LinearLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:background="@drawable/dialog_background">  //自定义一个颜色组成的背景


        <TextView
            android:id="@+id/title"
            android:layout_centerHorizontal="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="消息提示"
            android:layout_gravity="center"
            android:gravity="center"
            android:textColor="#38ADFF"
            android:textSize="16sp"
            android:layout_margin="15dp"
            />


        <TextView
            android:id="@+id/message"
            android:layout_below="@+id/title"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="12dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="提示消息"
            android:gravity="center"
            android:textSize="12sp"/>


        <View
            android:layout_below="@id/message"
            android:id="@+id/view"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="15dp"
            android:background="#E4E4E4"
            />
        <LinearLayout
            android:gravity="center"
            android:layout_below="@+id/view"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:orientation="horizontal"
            >
            <Button
                android:id="@+id/positive"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="确定"
                android:gravity="center"
                android:textColor="#38ADFF"
                android:textSize="16sp"
                android:background="@null"
                />


            <View
                android:layout_height="match_parent"
                android:layout_width="1dp"
                android:background="#E4E4E4"
                />


            <Button
                android:id="@+id/nagivate"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="确定"
                android:gravity="center"
                android:textColor="#38ADFF"
                android:textSize="16sp"
                android:background="@null"
                />


        </LinearLayout>
    </LinearLayout>


</RelativeLayout>


步骤3.定义一个颜色组成的背景(在drawable目录下建立dialog_background.xml)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <solid android:color="#ffffff"/>   //shape内部的填充色
    //描边的颜色
    <stroke android:color="#ffffff"
        android:width="0.8dp"/>       //描边的宽度
    <corners android:radius="6dp"/>   //四个角的圆形半径


</shape>


步骤4.自定义一个类extends   Dialog来实现我们的业务逻辑

package com.example.administrator.day_20;




import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MyDialog extends Dialog {


    private TextView title;     //标题
    private TextView message;   //信息


    private Button positive;    //确实按钮
    private Button nagivate;    //取消按钮


    //我们可以从外部设置控件的标题,以及信息,所以我们要定义字符串变量来接收外部的输入
    private String str_title;            //接收标题的
    private String str_message;          //接收信息的
    private String str_positive_btn;     //确定按钮的
    private String str_navigate_btn;     //取消按钮的




    //给确定跟取消按钮设置监听器
    private onPositiveListener positiveListener;
    private onNagivateListener nagivateListener;




    //定义确定,取消按钮的接口
    public  interface onPositiveListener{
        void onPositiveClick();
    }


    public  interface onNagivateListener{
        void onNagivateClick();
    }




    //定义public方法供外部给确定,取消按钮设置内容以及监听器
    public void setPositiveListener(String str_positive_btn,onPositiveListener onPositiveListener){
        if (str_positive_btn != null){
            this.str_positive_btn = str_positive_btn;
        }
        this.positiveListener = onPositiveListener;
    }


    public void setNagivateListener(String str_navigate_btn,onNagivateListener onNagivateListener){
        if (str_navigate_btn != null){
            this.str_navigate_btn = str_navigate_btn;
        }
        this.nagivateListener = onNagivateListener;
    }


    public void setTitle(String title) {
        this.str_title = title;
    }


    public void setMessage(String message) {
        this.str_message = message;
    }




    //该构造器一定要有,给自定义的Dialig引入我们刚刚创建的风格
    public MyDialog(@NonNull Context context) {
        super(context,R.style.MyDialog);
    }


    //像Activity一样Dialog创建时也会调用onCreate方法,
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //加载我们刚刚定义好的Dialog的布局
        setContentView(R.layout.my_dialog);
        //设置点击Dialog以外的地方不能让Dialog消失
        setCanceledOnTouchOutside(true);
        //初始化控件
        initView();
//        给控件设置初始的数据
        initData();
        //给控件添加各种事件
        initEvent();
    }
    //初始化我们一会会用到的控件
    public void initView(){
        positive = findViewById(R.id.positive);
        nagivate  = findViewById(R.id.nagivate);
        message = findViewById(R.id.message);
        title = findViewById(R.id.title);
    }
    //设置标题,消息,确定,取消按钮的内容
    public void initData(){
        if (str_message != null){
            message.setText(str_message);
        }


        if (str_title != null){
            title.setText(str_title);
        }


        if (str_positive_btn != null){
            positive.setText(str_positive_btn);
        }


        if (str_navigate_btn != null){
            nagivate.setText(str_navigate_btn);
        }
    }


    //给按钮设置点击事件
    public void initEvent(){
        positive.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (positiveListener != null){
                    positiveListener.onPositiveClick();
                }
            }
        });


        nagivate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (nagivate != null){
                    nagivateListener.onNagivateClick();
                }
            }
        });
    }


}

步骤5. 测试我们的功能

package com.example.administrator.day_20;


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;




public class MainActivity extends AppCompatActivity {
    private Button btn;
    private MyDialog myDialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myDialog = new MyDialog(MainActivity.this);
                myDialog.setTitle("Dialog");
                myDialog.setMessage("我是消息");
                myDialog.setNagivateListener(" 取消", new MyDialog.onNagivateListener() {
                    @Override
                    public void onNagivateClick() {
                        Toast.makeText(MainActivity.this,"取消按钮被点击了",Toast.LENGTH_SHORT).show();
                        myDialog.dismiss();
                    }
                });


                myDialog.setPositiveListener("确定", new MyDialog.onPositiveListener() {
                    @Override
                    public void onPositiveClick() {
                        Toast.makeText(MainActivity.this,"确定按钮被点击了",Toast.LENGTH_SHORT).show();
                        myDialog.dismiss();
                    }
                });
                myDialog.show();
            }
        });
    }
}