編輯:關於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不使用自定義布局情況下實現自定義通知欄圖標的方法
本文實例講述了Android不使用自定義布局情況下實現自定義通知欄圖標的方法。分享給大家供大家參考,具體如下:自定義通知欄圖標?不是很簡單麼。自定義布局都不在話下!是的,
Android的Bitmap和BitmapDrawable類解析-android學習之旅(六十)
使用簡單圖片使用Drawable對象bitmap和BitmapDrawable對象package peng.liu.test;import android.app.Act
A07_TimePicker & DatePicker & AnalogClock & DigitalClock 的設置小結
目標:學習時間日期和時鐘的設置 picker的計算機專業解釋是“選擇器”。 簡單翻譯一下: TimePicker 時間選擇器 DatePicker 日期選擇器 Analo
Android中使用DownloadManager下載並安裝apk
在前面,我介紹了使用 Volley 傳輸網絡數據。戳這裡Volley是一個很好用的網絡框架,但是Volley 不適合用來下載大的數據文件。因為 Volley 會保持在解析