Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之Buidler模式初探結合AlertDialog.Builder講解

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

編輯:關於Android編程

什麼是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(組裝)類使之能診斷"斷肢"斷在哪個部件上,再修復這個部件.

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved