AlertDialog源码分析

来源:互联网 发布:公司班车优化方案' 编辑:程序博客网 时间:2024/05/14 01:12

AlertDialog用的是builder模式构建,平常的用法大都是这样:

 AlertDialog.Builder builder = new AlertDialog.Builder(context);          builder.setIcon(R.drawable.icon);          builder.setTitle("Title");          builder.setMessage("Message");          builder.setPositiveButton("Button1",                  new DialogInterface.OnClickListener() {                      public void onClick(DialogInterface dialog, int whichButton) {                          setTitle("点击了对话框上的Button1");                      }                  });          builder.show();  

Builder是AlertDialog的一个内部类,负责构建AlertDialog。

Builder的主要代码如下(Android source ,api 19):

     public static class Builder {        private final AlertController.AlertParams P ;        private int mTheme;        /**         * Constructor using a context for this builder and the {@link AlertDialog} it creates.         */        public Builder(Context context) {            this(context , resolveDialogTheme(context, 0));        }        /**         * Set the title using the given resource id.         *         * @return This Builder object to allow for chaining of calls to set methods         */        public Builder setTitle(int titleId) {            P .mTitle = P.mContext .getText(titleId);            return this ;        }        /**         * Set the title displayed in the {@link Dialog}.         *         * @return This Builder object to allow for chaining of calls to set methods         */        public Builder setTitle(CharSequence title) {            P .mTitle = title;            return this ;        }        /**         * Set a listener to be invoked when the positive button of the dialog is pressed.         * @param textId The resource id of the text to display in the positive button         * @param listener The {@link DialogInterface.OnClickListener} to use.         *         * @return This Builder object to allow for chaining of calls to set methods         */        public Builder setPositiveButton(int textId, final OnClickListener listener) {            P .mPositiveButtonText = P.mContext .getText(textId);            P .mPositiveButtonListener = listener;            return this ;        }        /**         * Set a listener to be invoked when the positive button of the dialog is pressed.         * @param text The text to display in the positive button         * @param listener The {@link DialogInterface.OnClickListener} to use.         *         * @return This Builder object to allow for chaining of calls to set methods         */        public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {            P .mPositiveButtonText = text;            P .mPositiveButtonListener = listener;            return this ;        }        /**         * Set a listener to be invoked when the negative button of the dialog is pressed.         * @param textId The resource id of the text to display in the negative button         * @param listener The {@link DialogInterface.OnClickListener} to use.         *         * @return This Builder object to allow for chaining of calls to set methods         */        public Builder setNegativeButton(int textId, final OnClickListener listener) {            P .mNegativeButtonText = P.mContext .getText(textId);            P .mNegativeButtonListener = listener;            return this ;        }        /**         * Creates a {@link AlertDialog} with the arguments supplied to this builder. It does not         * {@link Dialog#show()} the dialog. This allows the user to do any extra processing         * before displaying the dialog. Use {@link #show()} if you don't have any other processing         * to do and want this to be created and displayed.         */        public AlertDialog create() {            final AlertDialog dialog = new AlertDialog (P. mContext, mTheme, false );            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;        }        /**         * Creates a {@link AlertDialog} with the arguments supplied to this builder and         * {@link Dialog#show()}'s the dialog.         */        public AlertDialog show() {            AlertDialog dialog = create();            dialog .show();            return dialog;        }    }

Builder中的设置各种属性其实就是设置的AlertController.AlertParams参数,最终在创建的时候用P.apply(dialog.mAlert)来应用所有的属性。apply这个函数调用的是AlertController中的各种设置属性的函数。而AlertDialog中的设置最终也是设置的AlertController。
AlertDialog中的主要设置如下:

public class AlertDialog extends Dialog implements DialogInterface {    private AlertController mAlert ;    protected AlertDialog (Context context) {        this(context , resolveDialogTheme(context, 0), true);    }    /**     * Construct an AlertDialog that uses an explicit theme.  The actual style     * that an AlertDialog uses is a private implementation, however you can     * here supply either the name of an attribute in the theme from which     * to get the dialog's style (such as {@link android.R.attr#alertDialogTheme}     * or one of the constants {@link #THEME_TRADITIONAL},     * {@link #THEME_HOLO_DARK}, or {@link #THEME_HOLO_LIGHT}.     */    protected AlertDialog (Context context, int theme ) {        this(context , theme, true);    }    AlertDialog(Context context , int theme, boolean createThemeContextWrapper) {        super(context , resolveDialogTheme(context, theme ), createThemeContextWrapper);        mWindow .alwaysReadCloseOnTouchAttr();        mAlert = new AlertController(getContext (), this , getWindow());    }    protected AlertDialog (Context context, boolean cancelable , OnCancelListener cancelListener) {        super(context , resolveDialogTheme(context, 0));        mWindow .alwaysReadCloseOnTouchAttr();        setCancelable (cancelable);        setOnCancelListener (cancelListener);        mAlert = new AlertController(context , this , getWindow());    }    /**     * Gets one of the buttons used in the dialog.     * <p>     * If a button does not exist in the dialog, null will be returned.     *     * @param whichButton The identifier of the button that should be returned.     *            For example, this can be     *            {@link DialogInterface#BUTTON_POSITIVE}.     * @return The button from the dialog, or null if a button does not exist.     */    public Button getButton (int whichButton ) {        return mAlert.getButton(whichButton );    }    /**     * Gets the list view used in the dialog.     *      * @return The {@link ListView} from the dialog.     */    public ListView getListView () {        return mAlert.getListView();    }    @Override    public void setTitle (CharSequence title) {        super.setTitle (title);        mAlert .setTitle(title);    }    /**     * @see Builder#setCustomTitle(View)     */    public void setCustomTitle (View customTitleView) {        mAlert .setCustomTitle(customTitleView);    }}

可以看到,AlertDialog中最终的设置属性是AlertController。
简单的UML图:
这里写图片描述

Android中Dialog是异步的

0 0
原创粉丝点击