編輯:關於Android編程
那麼要為何使用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方法。
這樣做有什麼實際作用呢?
在Java實際使用中,我們經常用到"池"(Pool)的概念,當資源提供者無法提供足夠的資源,並且這些資源需要被很多用戶反復共享時,就需要使用池。"池"實際是一段內存,當池中有一些復雜的資源的"斷肢"(比如數據庫的連接池,也許有時一個連接會中斷),如果循環再利用這些"斷肢",將提高內存使用效率,提高池的性能,而在這裡AlertDialog.builder就是這個池,修改Builder模式中p.apply(組裝)類使之能診斷"斷肢"斷在哪個部件上,再修復這個部件.
本文實例講述了Android不使用自定義布局情況下實現自定義通知欄圖標的方法。分享給大家供大家參考,具體如下:自定義通知欄圖標?不是很簡單麼。自定義布局都不在話下!是的,
使用簡單圖片使用Drawable對象bitmap和BitmapDrawable對象package peng.liu.test;import android.app.Act
目標:學習時間日期和時鐘的設置 picker的計算機專業解釋是“選擇器”。 簡單翻譯一下: TimePicker 時間選擇器 DatePicker 日期選擇器 Analo
在前面,我介紹了使用 Volley 傳輸網絡數據。戳這裡Volley是一個很好用的網絡框架,但是Volley 不適合用來下載大的數據文件。因為 Volley 會保持在解析