您的位置:首页 > 产品设计 > UI/UE

Builder模式——AlertDialog中的Builder简单应用

2016-11-02 14:54 204 查看

1.Alertdialog的使用

new AlertDialog.Builder(this)
.setTitle("对话框的标题")
.setMessage("对话框的内容")
.setIcon(R.drawable.ic_launcher)
.create()
.show();


以前对这种点点点的方式感到很好奇,对不对,为什么可以一直点点点的调用。看源码Builder的构造方法,builder是AlertDialog的静态内部类。

public static class Builder {
//略
public Builder(Context context) {
this(context, resolveDialogTheme(context, 0));
}
//...略

public Builder setTitle(int titleId) {
P.mTitle = P.mContext.getText(titleId);
return this;
}
public Builder setTitle(CharSequence title) {
P.mTitle = title;
return this;
}
//...略
}


发现一个很有趣的东西就是每次调用完方法返回的是this,也就是builder,每次都把自身返回回去,这就是点点点的调用原理。

然后发现调用的方法参数都赋值给了一个P,点开看是 AlertController的一个静态内部类AlertParams,定义了dialog中需要用到的比如说标题,图标,内容,确定,取消按钮等等

public int mIconId = 0;
public Drawable mIcon;
public CharSequence mTitle;
public CharSequence mMessage;
public CharSequence mPositiveButtonText;
//...略

void apply();
void createListView();


到此,我们发现我们调用的builder的set方法是给AlertParams赋值,赋值只有,调用create方法,将AlertParams赋值给AlertDialog,我们看下create的方法

public AlertDialog create() {
//新建一个AlertDialog
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
//调用AlertParams的apply方法
P.apply(dialog.mAlert);
//将p中的属性,即创建时赋值的属性赋值给dialog
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;
}


AlertParams的apply方法,将自身的参数赋值给AlertController,因为AlertController属于dialog,所以最终赋值给的是dialog的set方法

public void apply(AlertController dialog) {
if (mCustomTitleView != null) {
dialog.setCustomTitle(mCustomTitleView);
} else {
if (mTitle != null) {
dialog.setTitle(mTitle);
}
if (mIcon != null) {
dialog.setIcon(mIcon);
}
//...略
}
if (mMessage != null) {
dialog.setMessage(mMessage);
}

//...略

// For a list, the client can either supply an array of items or an
// adapter or a cursor
if ((mItems != null) || (mCursor != null) || (mAdapter != null)) {
createListView(dialog);
}
if (mView != null) {
if (mViewSpacingSpecified) {
dialog.setView(mView, mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
mViewSpacingBottom);
} else {
dialog.setView(mView);
}
} else if (mViewLayoutResId != 0) {
dialog.setView(mViewLayoutResId);
}


最后调用show,显示到window上

总结:可以发现,其实builder让代码看起来变多了,其实这基本上是所有设计模式的通病,会产生多余的对象,占用内存,但是稍微一注意就可以发现,这样写封装性真的很好,对外提供的只是builder入口,而且建造者独立,更加容易拓展。

注:在GOF中,设计模式是有Director,Builder,ConcreateBuilder,product四部分构成,但在实际应用中Director的部分经常被省略,灵活运用,无对错。如AlerDialog.Builder同时担任了ConcreateBuilder,Builder,Director的角色,简化了设计。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息