1. 程式人生 > >設計模式-Builder模式(一)

設計模式-Builder模式(一)

一,builder模式簡介

  1.    定義 將一個複雜物件的構建與他的表示分離,使得同樣的構建過程可以建立不同的表示。  
  2.    使用場景

        (1)相同的方法,不同的執行順序,產生不同的事件結果         (2)多個部件或零件,都可以裝配到一個物件,但是產生的執行結果不相同         (3)產品類非常複雜         (4)當初始化一個物件特別複雜,如引數多,且很多引數都具有預設值時

二,Android原始碼分析_AlertDialog  

  1.   例項

      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();     }               }  }