Android中AlertDialog, AltertDialog.Builder的基本用法与Builder模式

1. AltertDialog

Android中到处都是Dialog用来向用户展示信息和询问用户的选择。要使用Android的对话框非常简单,只需要使用AlterDialog这个类即可创建一个Android系统提供的标准样式的Dialog。
标准样式的Dialog含有一个或者二个或者三个按钮,可以显示标题和信息。
下面是一个最简单的Dialog的使用的Demo

public class MainActivity extends ActionBarActivity {
    private Button dialogButton;
    private DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            Toast.makeText(MainActivity.this, "Button" + which + "was clicked", Toast.LENGTH_SHORT).show();

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dialogButton = (Button)findViewById(R.id.dialog_button);
        dialogButton.setOnClickListener(new OnClickListener(){

            public void onClick(View v) {
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setTitle("Title");
                builder.setMessage("Hello AlertDialog");
                builder.setPositiveButton("Positive", listener);
                builder.setNegativeButton("Negative", listener);
                builder.setNeutralButton("Neutral", listener);
                AlertDialog dialog = builder.create();
                dialog.show();

                /*
                new AlertDialog.Builder(MainActivity.this)
                                .setTitle("Title")
                                .setMessage("Hello AlertDialog")
                                .setPositiveButton("Positive", listener)
                                .setNegativeButton("Negative", listener)
                                .setNeutralButton("Neutral", listener)
                                .create()
                                .show();*/
            }
        });
    }   
}

上面的示例向我们展示了Android的标准对话框的最基本用法。
点击Button,弹出Dialog。
对话框的五个基本元素
1. title: 设置Dialog的标题, setTitle(“Title”)。
2. Message: 设置Dialog的内容, setMessage(“Hello AlertDialog”)。
3. Positive Button: 设置Positive Button的文字及其回调,setPositiveButton(“Positive”, listener)。
4. Neutral Button: 设置Neutral Button的文字及其回调,setNeutralButton(“Neutral”, listener)
5. Negative: 设置Negative Button的文字及其回调,setNegativeButton(“Negative”, listener)
运行Demo程序,点击Button,弹出如下对话框:
    这里写图片描述

2. AlterDialog的构建者AlterDialog.Builder

在构造AlterDialog的时候,用到了AlterDialog.Builder这个类。首先创建了AlterDialog.Builder类,设置Builder的title,Message,Button及Button回调。在构建玩Builder类以后,调用Builder.Create,正式创建AlterDialog。这是为什么呢?
我们来看一下AlterDialog.Builder的源码,并以最简单的setTitle为例。
看一下最简单的

public static class Builder {
    private final AlertController.AlertParams P;
    private int mTheme;

    /**
     * Constructor using a context for this builder and the {@link AlertDialog} it creates.
     */
    public Builder(Context context) {
        this(context, resolveDialogTheme(context, 0));
    }


    public Builder(Context context, int theme) {
        P = new AlertController.AlertParams(new ContextThemeWrapper(
                context, resolveDialogTheme(context, theme)));
        mTheme = theme;
    }

    public Builder setTitle(CharSequence title) {
        P.mTitle = title;
        return this;
    }
    ....
    ....
     public AlertDialog create() {
        final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
        P.apply(dialog.mAlert);
        dialog.setCancelable(P.mCancelable);
        if (P.mCancelable) {
            dialog.setCanceledOnTouchOutside(true);
        }
        dialog.setOnCancelListener(P.mOnCancelListener);
        dialog.setOnDismissListener(P.mOnDismissListener);
        if (P.mOnKeyListener != null) {
            dialog.setOnKeyListener(P.mOnKeyListener);
        }
        return dialog;
    }
}

其中P是一个保存设置AlterDialog的参数类AlertParams的对象
很显然,Builder只是将AlterDialog的参数存放在一个参数对象里,做一个暂时的保存。
在最后调用create方法的时候,创建一个AlterDialog对象,将暂存的参数P一次性应用到这个Dialog对象上。完成Dialog的创建。
我们看到setTitle这样的函数的返回值是this,返回了本身,所以这样的函数可以用作连续调用。
所以Demo中的

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("Title"); 
builder.setMessage("Hello AlertDialog"); 
builder.setPositiveButton("Positive", listener); 
builder.setNegativeButton("Negative", listener); 
builder.setNeutralButton("Neutral", listener); 
AlertDialog dialog = builder.create(); dialog.show();

可以更简洁的写成

new AlertDialog.Builder(MainActivity.this)
    .setTitle("Title")
    .setMessage("Hello AlertDialog")
    .setPositiveButton("Positive", listener)
    .setNegativeButton("Negative", listener)
    .setNeutralButton("Neutral", listener)
    .create()
    .show();

如果我们想要创建一个AlterDialog对象,完全可以直接调用AlterDialog的构造函数,或者调用AlterDialog为我们提供setTitle,用来做参数设置。为什么Android要那么麻烦增加一个Builder类呢?

3 如果没有AlterDialog.Buidler

AlterDialog有很多的参数,如我们上面列举的title,message,三个button及其回调,除此以外还有icon,View等属性。如果Android不采用Builder,而采用普通的构造函数来设计AlterDialog,可能要写出很多类似于如下的构造函数:

AlertDialog(String title);
AlertDialog(String message)
AlertDialog(int resId)
AlertDialog(int resId, String title, String message);
AlterDialog(int resId, String title, String message, String PositiveButtonString, OnClickListener listener);
AlterDialog(int resId, String title, String message, String PositiveButtonString, OnClickListener listener);
AlterDialog(int resId, String title, String message, String NegativeButtonString, OnClickListener listener);
AlterDialog(int resId, String title, String message, String PositiveButtonString, OnClickListener listener, String NegativeButtonString, OnClickListener listener);
....

实际上由于AlterDialog的参数众多,组合众多,AlterDialog需要很多个构造函数,而且这将随着AlterDialog的参数的增加而急剧膨胀,最终失去控制。
所以重叠构造函数的方式是可行的,但是会使客户端的代码编写难度增加,且难以阅读。比如如下的客户端代码:

AlterDialog dialog = new AlterDialog("hello", "nihao");

如果用户手边没有API手册,无法记住”hello”和”nihao”,谁是title,谁是message。
那怎么办呢?我们可以借助于Builder模式

4 Builder模式

Builder模式:不直接生成想要的对象,而是让客户端利用构造函数构造一个Builder对象,然后客户端代码在Builder上调用setter方法,用来设置每个参数。最后调用Builder的create方法,生成真正想要的对象。
Builder首先构建了一个最基本的Builder实例,然后提供了一系列setter函数,就像为对象提供具名的可选参数。

AlterDialog.Builder就是Builder模式最好的应用,由于AlterDialog有很多个参数,如果采用构造函数直接构造AlterDialog,会产生构造函数膨胀,也增加了客户端在编写AlterDialog的代码的时候的难度。所以AlterDialog借助于其内部类,Builder,首先以最必须的参数(context)构造了一个Builder对象,然后依次调用setter(比如setTitle, setMessage….)函数,将AlterDialog的参数暂存起来,最后调用create函数,创建一个AlterDialog对象,并将之前暂存的参数一次性应用到该对象上。完成目标对象的创建。

Builder模式有几个好处:
1. Builder的setter函数可以包含安全检查,可以确保构建过程的安全,有效。
2. Builder的setter函数是具名函数,有意义,相对于构造函数的一长串函数列表,更容易阅读维护。
3. 可以利用单个Builder对象构建多个对象,Builder的参数可以在创建对象的时候利用setter函数进行调整

当然Builder模式也有缺点:
1. 更多的代码,需要Builder这样的内部类
2. 增加了类创建的运行时开销
但是当一个类参数很多的时候,Builder模式带来的好处要远胜于其缺点。

  • 14
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值