一,builder模式简介
- 定义
将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。
- 使用场景
(1)相同的方法,不同的执行顺序,产生不同的事件结果
(2)多个部件或零件,都可以装配到一个对象,但是产生的运行结果不相同
(3)产品类非常复杂
(4)当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时
二,Android源码分析_AlertDialog
- 实例
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("Titile");
builder.setIcon(R.mipmap.ic_launcher);
builder.setPositiveButton("button1", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog dialog=builder.create();
dialog.show();
2. 源码解析
public class AlertDialog extends AppCompatDialog implements DialogInterface {
public static class Builder {
private final AlertController.AlertParams P;
private final int mTheme;
1,//构造函数,使用默认的主题
public Builder(@NonNull Context context) {
this(context, resolveDialogTheme(context, 0));
}
//构造函数,使用明确的主题
public Builder(@NonNull Context context, @StyleRes int themeResId) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, themeResId)));
mTheme = themeResId;
}
2,设置各种参数
public Builder setTitle(@Nullable CharSequence title) {
P.mTitle = title;
return this;
}
public Builder setMessage(@Nullable CharSequence message) {
P.mMessage = message;
return this;
}
public Builder setIcon(@Nullable Drawable icon) {
P.mIcon = icon;
return this;
}
3,构建AlertDialog,并且将参数传递给AlertDialog
public AlertDialog create() {
4,构建AlertDialog
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
5,将p的参数应用到dialog的Alert对象中
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.apply(dialog.mAlert); 将p的参数应用到dialog的Alert对象中
class AlertController {
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 (mIconId != 0) {
dialog.setIcon(mIconId);
}
if (mIconAttrId != 0) {
dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
}
}
if (mMessage != null) {
dialog.setMessage(mMessage);
}
if (mPositiveButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_POSITIVE, mPositiveButtonText,
mPositiveButtonListener, null);
}
if (mNegativeButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mNegativeButtonText,
mNegativeButtonListener, null);
}
if (mNeutralButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_NEUTRAL, mNeutralButtonText,
mNeutralButtonListener, null);
}
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);
}
}
}
6,展示AlertDialog.show()
//AlertDialog的show()方法
public AlertDialog show() {
final AlertDialog dialog = create();
dialog.show();
return dialog;
}
//Dialog的show()方法
public class Dialog implements DialogInterface, Window.Callback,
KeyEvent.Callback, OnCreateContextMenuListener, Window.OnWindowDismissedCallback {
public void show() {
if (mShowing) {
if (mDecor != null) {
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
mDecor.setVisibility(View.VISIBLE);
}
return;
}
//1,调用AlertDialog的OnCreate()
if (!mCreated) {
dispatchOnCreate(null);
} else {
// Fill the DecorView in on any configuration changes that
// may have occured while it was removed from the WindowManager.
final Configuration config = mContext.getResources().getConfiguration();
mWindow.getDecorView().dispatchConfigurationChanged(config);
}
//2,调用AlertDialog的OnStart()
onStart();
//3,将AlertDialog的DecorView添加到windowManage
mDecor = mWindow.getDecorView();
//4,设置布局参数
WindowManager.LayoutParams l = mWindow.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
nl.copyFrom(l);
nl.softInputMode |=
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
l = nl;
}
//5,将AlertDialog的DecorView添加到windowManage
mWindowManager.addView(mDecor, l);
mShowing = true;
}
}
7,解析onCreate()
//Dialog中的onCreate()是一个空的方法,因此调用子类AlertDialog中的OnCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAlert.installContent();
}
class AlertController {
//将布局AlertDialog加载进来
public AlertController(Context context, AppCompatDialog di, Window window) {
mContext = context;
mDialog = di;
mWindow = window;
mHandler = new ButtonHandler(di);
final TypedArray a = context.obtainStyledAttributes(null, R.styleable.AlertDialog,
R.attr.alertDialogStyle, 0);
mAlertDialogLayout = a.getResourceId(R.styleable.AlertDialog_android_layout, 0);
mButtonPanelSideLayout = a.getResourceId(R.styleable.AlertDialog_buttonPanelSideLayout, 0);
mListLayout = a.getResourceId(R.styleable.AlertDialog_listLayout, 0);
mMultiChoiceItemLayout = a.getResourceId(R.styleable.AlertDialog_multiChoiceItemLayout, 0);
mSingleChoiceItemLayout = a
.getResourceId(R.styleable.AlertDialog_singleChoiceItemLayout, 0);
mListItemLayout = a.getResourceId(R.styleable.AlertDialog_listItemLayout, 0);
mShowTitle = a.getBoolean(R.styleable.AlertDialog_showTitle, true);
a.recycle();
/* We use a custom title so never request a window title */
di.supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
}
public void installContent() {
//构造函数中加载布局
final int contentView = selectContentView();
mDialog.setContentView(contentView);
//显示布局
setupView();
}
}
}