一、 介绍介绍Dialog

dialog嘛,大家很常用的。在Android中也经常使用各种dialog来弹出消息或者列出选项等等,可以说使用频率很高了。
现在很多APP都有自己优雅的dialog样式,也有各种丰富的功能,但是万变不离其宗,都是由基础的dialog一步一步学习来的(当然有些地方使用了别的形式,就像popupwindow等等),今天就由小德来介绍一下新手向·dialog基础使用。

二、Dialog,但是是AlertDialog

Android中提供了几种Dialog:AlertDialog,最常使用的对话框,用来弹出提示消息的;ProgressDialog,框如其名,带进度条的等等。这些都是继承自Dialog,我们就从AlertDialog的基础使用来开始。

1.AlertDialog是用什么创建的

AlertDialog有一个内部类:Builder,听名字就知道这个就是构建我们的AlertDialog的入口了,使用builder可以在构建dialog的时候设置好dialog的各种属性。
这是源码,我们只要清楚创建的时候要传入一个Context,返回的是Builder对象, 调用create(或show)方法返回的是AlertDialog对象。

/**
     * Creates a builder for an alert dialog that uses the default alert
     * dialog theme.
     * <p>
     * The default alert dialog theme is defined by
     * {@link android.R.attr#alertDialogTheme} within the parent
     * {@code context}'s theme.
     *
     * @param context the parent context
     */
    public Builder(Context context) {
        this(context, resolveDialogTheme(context, ResourceId.ID_NULL));
    }
复制代码

就像这样使用:

AlertDialog dialog = new AlertDialog.Builder(this).create();
复制代码

这时候那边的咕咕同学就要问了,为什么不直接new一个AlertDialog呢?

不愿意透漏姓名的咕咕同学->


原因上边也简单提到了,使用builder可以帮助我们构建dialog。

2.builder怎么个帮助法呢?

比如我们要设置dialog的title,我们就直接这样:

AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")//简单易懂的设置title
            .create();
复制代码

dialog总得有个确定button取消button这种的把:

AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")
            //可以直接设置这三种button
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog","click button ok");
                    dialog.dismiss();
                    //dissMiss方法会使dialog消失,并会调用OnDismissListener(如果有的话)
                    //其实这里不调用dissMiss,dialog也会消失,具体看下两个方法
                }
            })
            .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog","click button cancel");
                }
            })
            .setNeutralButton("忽略", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog","click button ignore");
                }
            })
            .create();
复制代码

我们dialog也得显示什么内容吧:

简单点,显示个字符串

使用setMessage方法

AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")
            //setMessage是用来显示字符串的
            .setMessage("message")
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog","click button ok");
                }
            })
            .create();
复制代码
显示多点东西,比如一个列表

使用setItems方法,参数1:要显示的item列表,参数2:点击事件的listener。这个listener有意思的地方在于有个参数which,表明点击的第几个item,当然,从0开始数。

String[] items = new String[]{"item1","item2"};
    AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")
            //设置列表
            .setItems(items, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                //注意这个which
                    Log.v("testDialog","click item"+String.valueOf(which));
                }
            })
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog","click button ok");
                }
            })
            .create();
复制代码
显示列表的第二种方法

使用Adapter,这就用到了setAdapter方法。不过注意我们在构造adapter的时候,需要指定item的布局文件和在布局文件中item的对应的Id。这也就是说我们可以通过布局文件来实现我们想要的特效。

String[] items = new String[]{"item1", "item2"};
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.item,R.id.tv_item, items);
    AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")
            .setAdapter(adapter, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog", "click: " + String.valueOf(which));
                }
            })
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog", "click button ok");
                }
            })
            .create();
复制代码
有的时候我们得显示个单选列表

使用setSingleChoiceItems,参数1:choice列表,参数2:默认选择的第几个choice,参数3:clickListener。

String[] choices = new String[]{"choice1","choice2"};
    AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")
            .setSingleChoiceItems(choices, 0, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog","choice "+String.valueOf(which));
                }
            })
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog","click button ok");
                }
            })
            .create();
复制代码
所以多选框也会来的

使用setMultiChoiceItems方法,和单选框大同小异,不过注意第二个参数,这个Boolean数组代表的是每一个选项的默认状态(开关)。

String[] choices = new String[]{"choice1","choice2"};
    boolean[] checked = new boolean[]{false,false};
    AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")
            .setMultiChoiceItems(choices, checked, new DialogInterface.OnMultiChoiceClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                    if(isChecked){
                        Log.v("testDialog","check "+String.valueOf(which));
                    } else {
                        Log.v("testDialog","unCheck "+String.valueOf(which));
                    }
                }
            })
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog","click button ok");
                }
            })
            .create();
复制代码
多复杂啊,所以来个view吧

使用setView方法,参数可以是view对象或者布局文件的资源Id。但是注意这个方法要求API level21以上。

AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")
            .setView(R.layout.list_dialog)
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog", "click button ok");
                }
            })
            .create();
复制代码

3.我要手动挡,不用builder

可以创建一个类继承自Dialog,然后重写方法。这里介绍第二种方法。

public static void showNormalDialog(Activity activity) {
    final Dialog dialog = new Dialog(activity);
    //使用LayoutInflater来获得dialog要显示的布局
    LinearLayout root = (LinearLayout) LayoutInflater.from(activity).inflate(R.layout.normal_dialog,null);
    root.findViewById(R.id.bt_ok).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.v("testDialog","click button ok");
            dialog.dismiss();
        }
    });
    dialog.setContentView(root);
    dialog.show();
}
复制代码

我们使用LayoutInflater来加载布局文件,设置好布局的属性之后使用setContentView来设置好。

4.不对,用了你的代码怎么没显示呢?

其实我上边的代码有个小坑,我最后使用的都是create方法来获得dialog对象,但是之后调用show才会显示出来,所以可以直接这样写:

AlertDialog dialog = new AlertDialog.Builder(this)
            .setTitle("title")
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.v("testDialog", "click button ok");
                }
            })
            .show();
复制代码

虽然逻辑上来说先create出来再显示比较好,但是看了看show的源码就知道了,Android早就考虑好了:

/**
     * Creates an {@link AlertDialog} with the arguments supplied to this
     * builder and immediately displays the dialog.
     * <p>
     * Calling this method is functionally identical to:
     * <pre>
     *     AlertDialog dialog = builder.create();
     *     dialog.show();
     * </pre>
     */
    public AlertDialog show() {
        final AlertDialog dialog = create();
        dialog.show();
        return dialog;
    }
复制代码



O了个银行家算法K


//作为Android开发的初学者,如果我有错误的地方或者不足的话欢迎大家指正。希望与大家一同进步