Android開發之Buidler模式初探結合AlertDialog.Builder講解

來源:互聯網
上載者:User

Android開發之Buidler模式初探結合AlertDialog.Builder講解
什麼是Buidler模式呢?就是將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示.Builder模式是一步一步建立一個複雜的對象,它允許使用者可以只通過指定複雜物件的類型和內容就可以構建它們.

那麼要為何使用Buidler呢?

是為了將構建複雜物件的過程和它的組件分開因為一個複雜的對象,不但有很多大量組成部分,如AlertDialog對話方塊,有很多組成組件,比如Tittle,Message,icon,PositiveButton等等,但遠不止這些,如何將這些組件裝配成一個AlertDialog對話方塊呢,這個裝配程可能也是一個很複雜的步驟,Builder模式就是為了將組件和組裝過程分開。通俗點說,就是我先分開生產好各個組件,然後交由另一個類去組裝這些組件。

如何使用?

我們來看一下Android內部關於AlertDialog.Builder的原始碼便可以知曉。

public class AlertDialog extends Dialog implements DialogInterface {      // Controller, 接受Builder成員變數P中的各個參數      private AlertController mAlert;         // 建構函式      protected AlertDialog(Context context, int theme) {          this(context, theme, true);      }         // 4 : 構造AlertDialog      AlertDialog(Context context, int theme, boolean createContextWrapper) {          super(context, resolveDialogTheme(context, theme), createContextWrapper);          mWindow.alwaysReadCloseOnTouchAttr();          mAlert = new AlertController(getContext(), this, getWindow());      }         // 實際上調用的是mAlert的setTitle方法      @Override      public void setTitle(CharSequence title) {          super.setTitle(title);          mAlert.setTitle(title);      }         // 實際上調用的是mAlert的setCustomTitle方法      public void setCustomTitle(View customTitleView) {          mAlert.setCustomTitle(customTitleView);      }             public void setMessage(CharSequence message) {          mAlert.setMessage(message);      }         // AlertDialog其他的代碼省略             // ************  Builder為AlertDialog的內部類   *******************      public static class Builder {          // 1 :該類用來儲存AlertDialog的各個參數, 例如title, message, icon等.          private final AlertController.AlertParams P;                              /**          * 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;          }                                  // 2:設定各種參數到P          public Builder setTitle(CharSequence title) {              P.mTitle = title;              return this;          }                                public Builder setMessage(CharSequence message) {              P.mMessage = message;              return this;          }             public Builder setIcon(int iconId) {              P.mIconId = iconId;              return this;          }                     public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {              P.mPositiveButtonText = text;              P.mPositiveButtonListener = listener;              return this;          }                                public Builder setView(View view) {              P.mView = view;              P.mViewSpacingSpecified = false;              return this;          }                     // 3 : 構建AlertDialog, 傳遞參數          public AlertDialog create() {              // 調用new AlertDialog構造對象, 並且將參數傳遞個體AlertDialog              final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);              // 5 : 將P中的參數應用的dialog中的mAlert對象中              //這一步是核心方法我們等下看源碼繼續講              P.apply(dialog.mAlert);              dialog.setCancelable(P.mCancelable);              if (P.mCancelable) {                  dialog.setCanceledOnTouchOutside(true);              }              dialog.setOnCancelListener(P.mOnCancelListener);              if (P.mOnKeyListener != null) {                  dialog.setOnKeyListener(P.mOnKeyListener);              }              return dialog;          }            public AlertDialog show() {              //6:顯示dialog              AlertDialog dialog = create();              dialog.show();              return dialog;          }      }         }
從上面的源碼中我們可以看到,對話方塊的構建是通過Builder來設定AlertDialog中的title, message, button等參數, 這些參數都儲存在類型為AlertController.AlertParams的成員變數P中,AlertController.AlertParams中包含了與之對應的成員變數。在調用Builder類的create函數時才建立AlertDialog, 並且將Builder成員變數P中儲存的參數應用到AlertDialog的mAlert對象中,最後調用dialog.show方法顯示對話方塊。

現在我們再來看看即P.apply(dialog.mAlert)程式碼片段。我們看看apply函數的實現 。

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 (mForceInverseBackground) {          dialog.setInverseBackgroundForced(true);      }      // 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);          }      }  }
實際上就是把P中的參數挨個的設定到AlertController中, 也就是AlertDialog中的mAlert對象。從AlertDialog的各個setter方法中我們也可以看到,實際上也都是調用了mAlert對應的setter方法。
綜上看完上面源碼之後我們就可以發現,怪不得我們平時調用對話方塊的時候可以直接使用,AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);不用Alert.Builder方法建立也可以,因為其本質是一樣的,Builder只是把組件的生產過程化成一步步實行而已。

這樣做有什麼實際作用呢?

在Java實際使用中,我們經常用到"池"(Pool)的概念,當資源提供者無法提供足夠的資源,並且這些資源需要被很多使用者反覆共用時,就需要使用池。"池"實際是一段記憶體,當池中有一些複雜的資源的"斷肢"(比如資料庫的串連池,也許有時一個串連會中斷),如果迴圈再利用這些"斷肢",將提高記憶體使用量效率,提高池的效能,而在這裡AlertDialog.builder就是這個池,修改Builder模式中p.apply(組裝)類使之能診斷"斷肢"斷在哪個組件上,再修複這個組件.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.