AlertDialog源码解析

按照惯例,先看类说明:

[java]  view plain copy
  1. A subclass of Dialog that can display one, two or three buttons. If you only want to display a String in this dialog box, use the setMessage() method. If you want to display a more complex view, look up the FrameLayout called "custom" and add your view to it:  
  2.   
  3.  FrameLayout fl = (FrameLayout) findViewById(android.R.id.custom);  
  4.  fl.addView(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));  
  5.    
  6. The AlertDialog class takes care of automatically setting WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM for you based on whether any views in the dialog return true from View.onCheckIsTextEditor(). Generally you want this set for a Dialog without text editors, so that it will be placed on top of the current input method UI. You can modify this behavior by forcing the flag to your desired mode after calling onCreate(Bundle).  

一个可以显示一个、二个或者三个按钮的Dialog,如果只是想在对话框窗体上显示一个String字符串,使用SetMessage方法。如果想要显示一些复杂的视图,可以自定义然后添加自己的视图如下:

[java]  view plain copy
  1. FrameLayout fl = (FrameLayout) findViewById(android.R.id.custom);  
  2.  fl.addView(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));  

在Dialog中不论你任何一个视图的View.onCheckIsTextEditor方法返回true,AlertDialog类会自动的为其设置WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM这个标志。一般情况下,如果一个Dialog中没有文本编辑,需要手动设置该标志,这样Dialog就会显示在当前输入法的上面。在调用onCreate方法后,可以通过设置标志使其达到想要的效果。

接着看全局变量:

[java]  view plain copy
  1. public class AlertDialog extends Dialog implements DialogInterface {  
  2.     private AlertController mAlert;  
  3.   
  4.     /** 
  5.      * Special theme constant for {@link #AlertDialog(Context, int)}: use 
  6.      * the traditional (pre-Holo) alert dialog theme. 
  7.      */  
  8.     public static final int THEME_TRADITIONAL = 1;  
  9.       
  10.     /** 
  11.      * Special theme constant for {@link #AlertDialog(Context, int)}: use 
  12.      * the holographic alert theme with a dark background. 
  13.      */  
  14.     public static final int THEME_HOLO_DARK = 2;  
  15.       
  16.     /** 
  17.      * Special theme constant for {@link #AlertDialog(Context, int)}: use 
  18.      * the holographic alert theme with a light background. 
  19.      */  
  20.     public static final int THEME_HOLO_LIGHT = 3;  
  21.   
  22.     /** 
  23.      * Special theme constant for {@link #AlertDialog(Context, int)}: use 
  24.      * the device's default alert theme with a dark background. 
  25.      */  
  26.     public static final int THEME_DEVICE_DEFAULT_DARK = 4;  
  27.   
  28.     /** 
  29.      * Special theme constant for {@link #AlertDialog(Context, int)}: use 
  30.      * the device's default alert theme with a dark background. 
  31.      */  
  32.     public static final int THEME_DEVICE_DEFAULT_LIGHT = 5;  

一个alertController和透明、全黑、全亮、设备默认黑色和设备默认亮色5中主题。

看一下构造函数:

[java]  view plain copy
  1. protected AlertDialog(Context context) {  
  2.         this(context, resolveDialogTheme(context, 0), true);  
  3.     }  
  4.   
  5.     /** 
  6.      * Construct an AlertDialog that uses an explicit theme.  The actual style 
  7.      * that an AlertDialog uses is a private implementation, however you can 
  8.      * here supply either the name of an attribute in the theme from which 
  9.      * to get the dialog's style (such as {@link android.R.attr#alertDialogTheme} 
  10.      * or one of the constants {@link #THEME_TRADITIONAL}, 
  11.      * {@link #THEME_HOLO_DARK}, or {@link #THEME_HOLO_LIGHT}. 
  12.      */  
  13.     protected AlertDialog(Context context, int theme) {  
  14.         this(context, theme, true);  
  15.     }  
  16.   
  17.     AlertDialog(Context context, int theme, boolean createContextWrapper) {  
  18.         super(context, resolveDialogTheme(context, theme), createContextWrapper);  
  19.         mWindow.alwaysReadCloseOnTouchAttr();  
  20.         mAlert = new AlertController(getContext(), this, getWindow());  
  21.     }  
  22.   
  23.     protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {  
  24.         super(context, resolveDialogTheme(context, 0));  
  25.         mWindow.alwaysReadCloseOnTouchAttr();  
  26.         setCancelable(cancelable);  
  27.         setOnCancelListener(cancelListener);  
  28.         mAlert = new AlertController(context, this, getWindow());  
  29.     }  

其构造方法均为protected或者权限更小的默认,所以我们不能在外部直接调用其构造方法初始化一个AlertDialog。而且第一个和第二个构造方法(自定义主题)都是调用个第三个构造方法,初始化了非常重要的AlertController类,而启动调用了resolveDialogTheme方法:

[java]  view plain copy
  1. static int resolveDialogTheme(Context context, int resid) {  
  2.         if (resid == THEME_TRADITIONAL) {  
  3.             return com.android.internal.R.style.Theme_Dialog_Alert;  
  4.         } else if (resid == THEME_HOLO_DARK) {  
  5.             return com.android.internal.R.style.Theme_Holo_Dialog_Alert;  
  6.         } else if (resid == THEME_HOLO_LIGHT) {  
  7.             return com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert;  
  8.         } else if (resid == THEME_DEVICE_DEFAULT_DARK) {  
  9.             return com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert;  
  10.         } else if (resid == THEME_DEVICE_DEFAULT_LIGHT) {  
  11.             return com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog_Alert;  
  12.         } else if (resid >= 0x01000000) {   // start of real resource IDs.  
  13.             return resid;  
  14.         } else {  
  15.             TypedValue outValue = new TypedValue();  
  16.             context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme,  
  17.                     outValue, true);  
  18.             return outValue.resourceId;  
  19.         }  
  20.     }  

确定Dialog主题,像在第一个Dialog中就是使用的系统默认主题:

[java]  view plain copy
  1. else {  
  2.             TypedValue outValue = new TypedValue();  
  3.             context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme,  
  4.                     outValue, true);  
  5.             return outValue.resourceId;  
  6.         }  
alwaysReadCloseOnTouchAttr是一个抽象方法,然后初始化AlertController。在第四个构造方法中,加了一个是否可以取消和CancelListener回调监听。

[java]  view plain copy
  1. /** 
  2.  * Gets one of the buttons used in the dialog. 
  3.  * <p> 
  4.  * If a button does not exist in the dialog, null will be returned. 
  5.  *  
  6.  * @param whichButton The identifier of the button that should be returned. 
  7.  *            For example, this can be 
  8.  *            {@link DialogInterface#BUTTON_POSITIVE}. 
  9.  * @return The button from the dialog, or null if a button does not exist. 
  10.  */  
  11. public Button getButton(int whichButton) {  
  12.     return mAlert.getButton(whichButton);  
  13. }  
  14.   
  15. /** 
  16.  * Gets the list view used in the dialog. 
  17.  *   
  18.  * @return The {@link ListView} from the dialog. 
  19.  */  
  20. public ListView getListView() {  
  21.     return mAlert.getListView();  
  22. }  
获取dialog中使用的Button和ListView,可以看到,均是调用AlertController类的方法实现。

[java]  view plain copy
  1. @Override  
  2. public void setTitle(CharSequence title) {  
  3.     super.setTitle(title);  
  4.     mAlert.setTitle(title);  
  5. }  

设置标题。

[java]  view plain copy
  1. /** 
  2.      * @see Builder#setCustomTitle(View) 
  3.      */  
  4.     public void setCustomTitle(View customTitleView) {  
  5.         mAlert.setCustomTitle(customTitleView);  
  6.     }  
设置一个自定义视图为标题。

[java]  view plain copy
  1. public void setMessage(CharSequence message) {  
  2.      mAlert.setMessage(message);  
  3.  }  

设置显示的消息。

[java]  view plain copy
  1. /** 
  2.  * Set the view to display in that dialog. 
  3.  */  
  4. public void setView(View view) {  
  5.     mAlert.setView(view);  
  6. }  
  7.   
  8. /** 
  9.  * Set the view to display in that dialog, specifying the spacing to appear around that  
  10.  * view. 
  11.  * 
  12.  * @param view The view to show in the content area of the dialog 
  13.  * @param viewSpacingLeft Extra space to appear to the left of {@code view} 
  14.  * @param viewSpacingTop Extra space to appear above {@code view} 
  15.  * @param viewSpacingRight Extra space to appear to the right of {@code view} 
  16.  * @param viewSpacingBottom Extra space to appear below {@code view} 
  17.  */  
  18. public void setView(View view, int viewSpacingLeft, int viewSpacingTop, int viewSpacingRight,  
  19.         int viewSpacingBottom) {  
  20.     mAlert.setView(view, viewSpacingLeft, viewSpacingTop, viewSpacingRight, viewSpacingBottom);  
  21. }  

设置显示的视图,第二个方法里面加上了边距。

[java]  view plain copy
  1. /** 
  2.      * Set a message to be sent when a button is pressed. 
  3.      *  
  4.      * @param whichButton Which button to set the message for, can be one of 
  5.      *            {@link DialogInterface#BUTTON_POSITIVE}, 
  6.      *            {@link DialogInterface#BUTTON_NEGATIVE}, or 
  7.      *            {@link DialogInterface#BUTTON_NEUTRAL} 
  8.      * @param text The text to display in positive button. 
  9.      * @param msg The {@link Message} to be sent when clicked. 
  10.      */  
  11.     public void setButton(int whichButton, CharSequence text, Message msg) {  
  12.         mAlert.setButton(whichButton, text, null, msg);  
  13.     }  
  14.       
  15.     /** 
  16.      * Set a listener to be invoked when the positive button of the dialog is pressed. 
  17.      *  
  18.      * @param whichButton Which button to set the listener on, can be one of 
  19.      *            {@link DialogInterface#BUTTON_POSITIVE}, 
  20.      *            {@link DialogInterface#BUTTON_NEGATIVE}, or 
  21.      *            {@link DialogInterface#BUTTON_NEUTRAL} 
  22.      * @param text The text to display in positive button. 
  23.      * @param listener The {@link DialogInterface.OnClickListener} to use. 
  24.      */  
  25.     public void setButton(int whichButton, CharSequence text, OnClickListener listener) {  
  26.         mAlert.setButton(whichButton, text, listener, null);  
  27.     }  
  28.   
  29.     /** 
  30.      * @deprecated Use {@link #setButton(int, CharSequence, Message)} with 
  31.      *             {@link DialogInterface#BUTTON_POSITIVE}. 
  32.      */  
  33.     @Deprecated  
  34.     public void setButton(CharSequence text, Message msg) {  
  35.         setButton(BUTTON_POSITIVE, text, msg);  
  36.     }  
  37.           
  38.     /** 
  39.      * @deprecated Use {@link #setButton(int, CharSequence, Message)} with 
  40.      *             {@link DialogInterface#BUTTON_NEGATIVE}. 
  41.      */  
  42.     @Deprecated  
  43.     public void setButton2(CharSequence text, Message msg) {  
  44.         setButton(BUTTON_NEGATIVE, text, msg);  
  45.     }  
  46.   
  47.     /** 
  48.      * @deprecated Use {@link #setButton(int, CharSequence, Message)} with 
  49.      *             {@link DialogInterface#BUTTON_NEUTRAL}. 
  50.      */  
  51.     @Deprecated  
  52.     public void setButton3(CharSequence text, Message msg) {  
  53.         setButton(BUTTON_NEUTRAL, text, msg);  
  54.     }  
  55.   
  56.     /** 
  57.      * Set a listener to be invoked when button 1 of the dialog is pressed. 
  58.      *  
  59.      * @param text The text to display in button 1. 
  60.      * @param listener The {@link DialogInterface.OnClickListener} to use. 
  61.      * @deprecated Use 
  62.      *             {@link #setButton(int, CharSequence, android.content.DialogInterface.OnClickListener)} 
  63.      *             with {@link DialogInterface#BUTTON_POSITIVE} 
  64.      */  
  65.     @Deprecated  
  66.     public void setButton(CharSequence text, final OnClickListener listener) {  
  67.         setButton(BUTTON_POSITIVE, text, listener);  
  68.     }  
  69.   
  70.     /** 
  71.      * Set a listener to be invoked when button 2 of the dialog is pressed. 
  72.      * @param text The text to display in button 2. 
  73.      * @param listener The {@link DialogInterface.OnClickListener} to use. 
  74.      * @deprecated Use 
  75.      *             {@link #setButton(int, CharSequence, android.content.DialogInterface.OnClickListener)} 
  76.      *             with {@link DialogInterface#BUTTON_NEGATIVE} 
  77.      */  
  78.     @Deprecated  
  79.     public void setButton2(CharSequence text, final OnClickListener listener) {  
  80.         setButton(BUTTON_NEGATIVE, text, listener);  
  81.     }  
  82.   
  83.     /** 
  84.      * Set a listener to be invoked when button 3 of the dialog is pressed. 
  85.      * @param text The text to display in button 3. 
  86.      * @param listener The {@link DialogInterface.OnClickListener} to use. 
  87.      * @deprecated Use 
  88.      *             {@link #setButton(int, CharSequence, android.content.DialogInterface.OnClickListener)} 
  89.      *             with {@link DialogInterface#BUTTON_POSITIVE} 
  90.      */  
  91.     @Deprecated  
  92.     public void setButton3(CharSequence text, final OnClickListener listener) {  
  93.         setButton(BUTTON_NEUTRAL, text, listener);  
  94.     }  

后面的六个方法都被Deprecated掉,不用看了,第一个方法里面设置某个Button(DialogInterface里面的BUTTON_POSITIVE、BUTTON_NEGATIVE、BUTTON_NEUTRAL三个中的一个)被点击以后发送的消息,有可能是,第二个方法里面为其中的一个Button设置点击响应监听。

[java]  view plain copy
  1. /** 
  2.  * Set resId to 0 if you don't want an icon. 
  3.  * @param resId the resourceId of the drawable to use as the icon or 0 
  4.  * if you don't want an icon. 
  5.  */  
  6. public void setIcon(int resId) {  
  7.     mAlert.setIcon(resId);  
  8. }  
  9.   
  10. public void setIcon(Drawable icon) {  
  11.     mAlert.setIcon(icon);  
  12. }  
  13.   
  14. /** 
  15.  * Set an icon as supplied by a theme attribute. e.g. android.R.attr.alertDialogIcon 
  16.  * 
  17.  * @param attrId ID of a theme attribute that points to a drawable resource. 
  18.  */  
  19. public void setIconAttribute(int attrId) {  
  20.     TypedValue out = new TypedValue();  
  21.     mContext.getTheme().resolveAttribute(attrId, out, true);  
  22.     mAlert.setIcon(out.resourceId);  
  23. }  

设置头部图标。

[java]  view plain copy
  1. public void setInverseBackgroundForced(boolean forceInverseBackground) {  
  2.         mAlert.setInverseBackgroundForced(forceInverseBackground);  
  3.     }  

设置AlertDialog 后面的窗体是否能够获得焦点(能不能响应用户操作触发的事件)

[java]  view plain copy
  1. @Override  
  2.  protected void onCreate(Bundle savedInstanceState) {  
  3.      super.onCreate(savedInstanceState);  
  4.      mAlert.installContent();  
  5.  }  

onCreate方法,初始化AlertController。

[java]  view plain copy
  1. @Override  
  2. public boolean onKeyDown(int keyCode, KeyEvent event) {  
  3.     if (mAlert.onKeyDown(keyCode, event)) return true;  
  4.     return super.onKeyDown(keyCode, event);  
  5. }  
  6.   
  7. @Override  
  8. public boolean onKeyUp(int keyCode, KeyEvent event) {  
  9.     if (mAlert.onKeyUp(keyCode, event)) return true;  
  10.     return super.onKeyUp(keyCode, event);  
  11. }  

按键事件,如果AlertController不处理则交给父类Dialog处理。


在上面AlertDialog的的各种设置方法,均是调用AlertController类中的方法实现,请参考android源码浅析--AlertController。

下面就是Builder类了,它是AlertDialog中的内部类:

[java]  view plain copy
  1. public static class Builder {  
  2.         private final AlertController.AlertParams P;  
  3.         private int mTheme;  
  4.           
  5.         /** 
  6.          * Constructor using a context for this builder and the {@link AlertDialog} it creates. 
  7.          */  
  8.         public Builder(Context context) {  
  9.             this(context, resolveDialogTheme(context, 0));  
  10.         }  
  11.   
  12.         /** 
  13.          * Constructor using a context and theme for this builder and 
  14.          * the {@link AlertDialog} it creates.  The actual theme 
  15.          * that an AlertDialog uses is a private implementation, however you can 
  16.          * here supply either the name of an attribute in the theme from which 
  17.          * to get the dialog's style (such as {@link android.R.attr#alertDialogTheme} 
  18.          * or one of the constants 
  19.          * {@link AlertDialog#THEME_TRADITIONAL AlertDialog.THEME_TRADITIONAL}, 
  20.          * {@link AlertDialog#THEME_HOLO_DARK AlertDialog.THEME_HOLO_DARK}, or 
  21.          * {@link AlertDialog#THEME_HOLO_LIGHT AlertDialog.THEME_HOLO_LIGHT}. 
  22.          */  
  23.         public Builder(Context context, int theme) {  
  24.             P = new AlertController.AlertParams(new ContextThemeWrapper(  
  25.                     context, resolveDialogTheme(context, theme)));  
  26.             mTheme = theme;  
  27.         }  

其全局变量为一个AlertController的参数和一个主题。其构造方法为初始化两个参数。注意theme这个参数,可以传入一个自定义的主体,设置如显示文字大小颜色等。

[java]  view plain copy
  1. /** 
  2.         * Returns a {@link Context} with the appropriate theme for dialogs created by this Builder. 
  3.         * Applications should use this Context for obtaining LayoutInflaters for inflating views 
  4.         * that will be used in the resulting dialogs, as it will cause views to be inflated with 
  5.         * the correct theme. 
  6.         * 
  7.         * @return A Context for built Dialogs. 
  8.         */  
  9.        public Context getContext() {  
  10.            return P.mContext;  
  11.        }  

        为Dialog返回一个在Builder创建时有其对应主题的Context。程序会使用这个Context去获取LayoutInflater去载入(填充?inflate怎么翻译才好呢?如有好的见解,请在下面留言多多指教)一个用于显示在正在生成的dialog的使用正确主题的视图。

[java]  view plain copy
  1. /** 
  2.  * Set the title using the given resource id. 
  3.  * 
  4.  * @return This Builder object to allow for chaining of calls to set methods 
  5.  */  
  6. public Builder setTitle(int titleId) {  
  7.     P.mTitle = P.mContext.getText(titleId);  
  8.     return this;  
  9. }  
  10.   
  11. /** 
  12.  * Set the title displayed in the {@link Dialog}. 
  13.  * 
  14.  * @return This Builder object to allow for chaining of calls to set methods 
  15.  */  
  16. public Builder setTitle(CharSequence title) {  
  17.     P.mTitle = title;  
  18.     return this;  
  19. }  
  20.   
  21. /** 
  22.  * Set the title using the custom view {@code customTitleView}. The 
  23.  * methods {@link #setTitle(int)} and {@link #setIcon(int)} should be 
  24.  * sufficient for most titles, but this is provided if the title needs 
  25.  * more customization. Using this will replace the title and icon set 
  26.  * via the other methods. 
  27.  *  
  28.  * @param customTitleView The custom view to use as the title. 
  29.  * 
  30.  * @return This Builder object to allow for chaining of calls to set methods 
  31.  */  
  32. public Builder setCustomTitle(View customTitleView) {  
  33.     P.mCustomTitleView = customTitleView;  
  34.     return this;  
  35. }  

设置标题,第三个使用搞一个自定义视图作为标题,然后注意这里的返回值都是其自身。

[java]  view plain copy
  1. /** 
  2.  * Set the message to display using the given resource id. 
  3.  * 
  4.  * @return This Builder object to allow for chaining of calls to set methods 
  5.  */  
  6. public Builder setMessage(int messageId) {  
  7.     P.mMessage = P.mContext.getText(messageId);  
  8.     return this;  
  9. }  
  10.   
  11. /** 
  12.  * Set the message to display. 
  13.   * 
  14.  * @return This Builder object to allow for chaining of calls to set methods 
  15.  */  
  16. public Builder setMessage(CharSequence message) {  
  17.     P.mMessage = message;  
  18.     return this;  
  19. }  

设置显示文本内容。

[java]  view plain copy
  1. /** 
  2.          * Set the resource id of the {@link Drawable} to be used in the title. 
  3.          * 
  4.          * @return This Builder object to allow for chaining of calls to set methods 
  5.          */  
  6.         public Builder setIcon(int iconId) {  
  7.             P.mIconId = iconId;  
  8.             return this;  
  9.         }  
  10.           
  11.         /** 
  12.          * Set the {@link Drawable} to be used in the title. 
  13.           * 
  14.          * @return This Builder object to allow for chaining of calls to set methods 
  15.          */  
  16.         public Builder setIcon(Drawable icon) {  
  17.             P.mIcon = icon;  
  18.             return this;  
  19.         }  
  20.   
  21.         /** 
  22.          * Set an icon as supplied by a theme attribute. e.g. android.R.attr.alertDialogIcon 
  23.          * 
  24.          * @param attrId ID of a theme attribute that points to a drawable resource. 
  25.          */  
  26.         public Builder setIconAttribute(int attrId) {  
  27.             TypedValue out = new TypedValue();  
  28.             P.mContext.getTheme().resolveAttribute(attrId, out, true);  
  29.             P.mIconId = out.resourceId;  
  30.             return this;  
  31.         }  

设置头部图标。

[java]  view plain copy
  1. /** 
  2.   * Set a listener to be invoked when the positive button of the dialog is pressed. 
  3.   * @param textId The resource id of the text to display in the positive button 
  4.   * @param listener The {@link DialogInterface.OnClickListener} to use. 
  5.   * 
  6.   * @return This Builder object to allow for chaining of calls to set methods 
  7.   */  
  8.  public Builder setPositiveButton(int textId, final OnClickListener listener) {  
  9.      P.mPositiveButtonText = P.mContext.getText(textId);  
  10.      P.mPositiveButtonListener = listener;  
  11.      return this;  
  12.  }  
  13.    
  14.  /** 
  15.   * Set a listener to be invoked when the positive button of the dialog is pressed. 
  16.   * @param text The text to display in the positive button 
  17.   * @param listener The {@link DialogInterface.OnClickListener} to use. 
  18.   * 
  19.   * @return This Builder object to allow for chaining of calls to set methods 
  20.   */  
  21.  public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {  
  22.      P.mPositiveButtonText = text;  
  23.      P.mPositiveButtonListener = listener;  
  24.      return this;  
  25.  }  

设置确定按钮,在这里可以看到,基本上都是设置AlertController.AlertParams P的值。以后会看一下AlertController这个类。

[java]  view plain copy
  1. /** 
  2.          * Set a listener to be invoked when the negative button of the dialog is pressed. 
  3.          * @param textId The resource id of the text to display in the negative button 
  4.          * @param listener The {@link DialogInterface.OnClickListener} to use. 
  5.          * 
  6.          * @return This Builder object to allow for chaining of calls to set methods 
  7.          */  
  8.         public Builder setNegativeButton(int textId, final OnClickListener listener) {  
  9.             P.mNegativeButtonText = P.mContext.getText(textId);  
  10.             P.mNegativeButtonListener = listener;  
  11.             return this;  
  12.         }  
  13.           
  14.         /** 
  15.          * Set a listener to be invoked when the negative button of the dialog is pressed. 
  16.          * @param text The text to display in the negative button 
  17.          * @param listener The {@link DialogInterface.OnClickListener} to use. 
  18.          * 
  19.          * @return This Builder object to allow for chaining of calls to set methods 
  20.          */  
  21.         public Builder setNegativeButton(CharSequence text, final OnClickListener listener) {  
  22.             P.mNegativeButtonText = text;  
  23.             P.mNegativeButtonListener = listener;  
  24.             return this;  
  25.         }  

设置取消按钮,里面都有一个回调监听,当按钮被按下时,可以自定义一些事件。

[java]  view plain copy
  1. /** 
  2.  * Set a listener to be invoked when the neutral button of the dialog is pressed. 
  3.  * @param textId The resource id of the text to display in the neutral button 
  4.  * @param listener The {@link DialogInterface.OnClickListener} to use. 
  5.  * 
  6.  * @return This Builder object to allow for chaining of calls to set methods 
  7.  */  
  8. public Builder setNeutralButton(int textId, final OnClickListener listener) {  
  9.     P.mNeutralButtonText = P.mContext.getText(textId);  
  10.     P.mNeutralButtonListener = listener;  
  11.     return this;  
  12. }  
  13.   
  14. /** 
  15.  * Set a listener to be invoked when the neutral button of the dialog is pressed. 
  16.  * @param text The text to display in the neutral button 
  17.  * @param listener The {@link DialogInterface.OnClickListener} to use. 
  18.  * 
  19.  * @return This Builder object to allow for chaining of calls to set methods 
  20.  */  
  21. public Builder setNeutralButton(CharSequence text, final OnClickListener listener) {  
  22.     P.mNeutralButtonText = text;  
  23.     P.mNeutralButtonListener = listener;  
  24.     return this;  
  25. }  

设置中立按钮。

[java]  view plain copy
  1. /** 
  2.  * Sets whether the dialog is cancelable or not.  Default is true. 
  3.  * 
  4.  * @return This Builder object to allow for chaining of calls to set methods 
  5.  */  
  6. public Builder setCancelable(boolean cancelable) {  
  7.     P.mCancelable = cancelable;  
  8.     return this;  
  9. }  

设置Dialog是否可以被取消,默认为true。

[java]  view plain copy
  1. /** 
  2.  * Sets the callback that will be called if the dialog is canceled. 
  3.  * @see #setCancelable(boolean) 
  4.  * 
  5.  * @return This Builder object to allow for chaining of calls to set methods 
  6.  */  
  7. public Builder setOnCancelListener(OnCancelListener onCancelListener) {  
  8.     P.mOnCancelListener = onCancelListener;  
  9.     return this;  
  10. }  

为dialog设置一个取消时的回调监听。
[java]  view plain copy
  1. /** 
  2.  * Sets the callback that will be called if a key is dispatched to the dialog. 
  3.  * 
  4.  * @return This Builder object to allow for chaining of calls to set methods 
  5.  */  
  6. public Builder setOnKeyListener(OnKeyListener onKeyListener) {  
  7.     P.mOnKeyListener = onKeyListener;  
  8.     return this;  
  9. }  
设一个按键监听,当dialog中的按键被按下时,会回调监听器中方法。

[java]  view plain copy
  1. /** 
  2.          * Set a list of items to be displayed in the dialog as the content, you will be notified of the 
  3.          * selected item via the supplied listener. This should be an array type i.e. R.array.foo 
  4.          * 
  5.          * @return This Builder object to allow for chaining of calls to set methods 
  6.          */  
  7.         public Builder setItems(int itemsId, final OnClickListener listener) {  
  8.             P.mItems = P.mContext.getResources().getTextArray(itemsId);  
  9.             P.mOnClickListener = listener;  
  10.             return this;  
  11.         }  
  12.           
  13.         /** 
  14.          * Set a list of items to be displayed in the dialog as the content, you will be notified of the 
  15.          * selected item via the supplied listener. 
  16.          * 
  17.          * @return This Builder object to allow for chaining of calls to set methods 
  18.          */  
  19.         public Builder setItems(CharSequence[] items, final OnClickListener listener) {  
  20.             P.mItems = items;  
  21.             P.mOnClickListener = listener;  
  22.             return this;  
  23.         }  

设置显示在Dialog中的Item列表和当item被点击时响应的监听器。

[java]  view plain copy
  1. /** 
  2.  * Set a list of items, which are supplied by the given {@link ListAdapter}, to be 
  3.  * displayed in the dialog as the content, you will be notified of the 
  4.  * selected item via the supplied listener. 
  5.  *  
  6.  * @param adapter The {@link ListAdapter} to supply the list of items 
  7.  * @param listener The listener that will be called when an item is clicked. 
  8.  * 
  9.  * @return This Builder object to allow for chaining of calls to set methods 
  10.  */  
  11. public Builder setAdapter(final ListAdapter adapter, final OnClickListener listener) {  
  12.     P.mAdapter = adapter;  
  13.     P.mOnClickListener = listener;  
  14.     return this;  
  15. }  

设置一个由ListAdapter提供内容的item列表作为显示在对话框的内容,当item被选择的时候会有一个回调监听。

[java]  view plain copy
  1. /** 
  2.          * Set a list of items, which are supplied by the given {@link Cursor}, to be 
  3.          * displayed in the dialog as the content, you will be notified of the 
  4.          * selected item via the supplied listener. 
  5.          *  
  6.          * @param cursor The {@link Cursor} to supply the list of items 
  7.          * @param listener The listener that will be called when an item is clicked. 
  8.          * @param labelColumn The column name on the cursor containing the string to display 
  9.          *          in the label. 
  10.          * 
  11.          * @return This Builder object to allow for chaining of calls to set methods 
  12.          */  
  13.         public Builder setCursor(final Cursor cursor, final OnClickListener listener,  
  14.                 String labelColumn) {  
  15.             P.mCursor = cursor;  
  16.             P.mLabelColumn = labelColumn;  
  17.             P.mOnClickListener = listener;  
  18.             return this;  
  19.         }  

设置一个由Cursor提供内容的item列表作为显示在对话框的内容,当item被选择的时候会有一个回调监听。lableColumn为Cursor中显示在文本标签上的列名。

[java]  view plain copy
  1. /** 
  2.  * Set a list of items to be displayed in the dialog as the content, 
  3.  * you will be notified of the selected item via the supplied listener. 
  4.  * This should be an array type, e.g. R.array.foo. The list will have 
  5.  * a check mark displayed to the right of the text for each checked 
  6.  * item. Clicking on an item in the list will not dismiss the dialog. 
  7.  * Clicking on a button will dismiss the dialog. 
  8.  *  
  9.  * @param itemsId the resource id of an array i.e. R.array.foo 
  10.  * @param checkedItems specifies which items are checked. It should be null in which case no 
  11.  *        items are checked. If non null it must be exactly the same length as the array of 
  12.  *        items. 
  13.  * @param listener notified when an item on the list is clicked. The dialog will not be 
  14.  *        dismissed when an item is clicked. It will only be dismissed if clicked on a 
  15.  *        button, if no buttons are supplied it's up to the user to dismiss the dialog. 
  16.  * 
  17.  * @return This Builder object to allow for chaining of calls to set methods 
  18.  */  
  19. public Builder setMultiChoiceItems(int itemsId, boolean[] checkedItems,   
  20.         final OnMultiChoiceClickListener listener) {  
  21.     P.mItems = P.mContext.getResources().getTextArray(itemsId);  
  22.     P.mOnCheckboxClickListener = listener;  
  23.     P.mCheckedItems = checkedItems;  
  24.     P.mIsMultiChoice = true;  
  25.     return this;  
  26. }  
  27.   
  28. /** 
  29.  * Set a list of items to be displayed in the dialog as the content, 
  30.  * you will be notified of the selected item via the supplied listener. 
  31.  * The list will have a check mark displayed to the right of the text 
  32.  * for each checked item. Clicking on an item in the list will not 
  33.  * dismiss the dialog. Clicking on a button will dismiss the dialog. 
  34.  *  
  35.  * @param items the text of the items to be displayed in the list. 
  36.  * @param checkedItems specifies which items are checked. It should be null in which case no 
  37.  *        items are checked. If non null it must be exactly the same length as the array of 
  38.  *        items. 
  39.  * @param listener notified when an item on the list is clicked. The dialog will not be 
  40.  *        dismissed when an item is clicked. It will only be dismissed if clicked on a 
  41.  *        button, if no buttons are supplied it's up to the user to dismiss the dialog. 
  42.  * 
  43.  * @return This Builder object to allow for chaining of calls to set methods 
  44.  */  
  45. public Builder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,   
  46.         final OnMultiChoiceClickListener listener) {  
  47.     P.mItems = items;  
  48.     P.mOnCheckboxClickListener = listener;  
  49.     P.mCheckedItems = checkedItems;  
  50.     P.mIsMultiChoice = true;  
  51.     return this;  
  52. }  
  53.   
  54. /** 
  55.  * Set a list of items to be displayed in the dialog as the content, 
  56.  * you will be notified of the selected item via the supplied listener. 
  57.  * The list will have a check mark displayed to the right of the text 
  58.  * for each checked item. Clicking on an item in the list will not 
  59.  * dismiss the dialog. Clicking on a button will dismiss the dialog. 
  60.  *  
  61.  * @param cursor the cursor used to provide the items. 
  62.  * @param isCheckedColumn specifies the column name on the cursor to use to determine 
  63.  *        whether a checkbox is checked or not. It must return an integer value where 1 
  64.  *        means checked and 0 means unchecked. 
  65.  * @param labelColumn The column name on the cursor containing the string to display in the 
  66.  *        label. 
  67.  * @param listener notified when an item on the list is clicked. The dialog will not be 
  68.  *        dismissed when an item is clicked. It will only be dismissed if clicked on a 
  69.  *        button, if no buttons are supplied it's up to the user to dismiss the dialog. 
  70.  * 
  71.  * @return This Builder object to allow for chaining of calls to set methods 
  72.  */  
  73. public Builder setMultiChoiceItems(Cursor cursor, String isCheckedColumn, String labelColumn,   
  74.         final OnMultiChoiceClickListener listener) {  
  75.     P.mCursor = cursor;  
  76.     P.mOnCheckboxClickListener = listener;  
  77.     P.mIsCheckedColumn = isCheckedColumn;  
  78.     P.mLabelColumn = labelColumn;  
  79.     P.mIsMultiChoice = true;  
  80.     return this;  
  81. }  

提供一个包含可以多选的listView的Dialog,设置一个多选监听,当item被选中时,监听回调会被触发。

[java]  view plain copy
  1. /** 
  2.  * Set a list of items to be displayed in the dialog as the content, you will be notified of 
  3.  * the selected item via the supplied listener. This should be an array type i.e. 
  4.  * R.array.foo The list will have a check mark displayed to the right of the text for the 
  5.  * checked item. Clicking on an item in the list will not dismiss the dialog. Clicking on a 
  6.  * button will dismiss the dialog. 
  7.  *  
  8.  * @param itemsId the resource id of an array i.e. R.array.foo 
  9.  * @param checkedItem specifies which item is checked. If -1 no items are checked. 
  10.  * @param listener notified when an item on the list is clicked. The dialog will not be 
  11.  *        dismissed when an item is clicked. It will only be dismissed if clicked on a 
  12.  *        button, if no buttons are supplied it's up to the user to dismiss the dialog. 
  13.  * 
  14.  * @return This Builder object to allow for chaining of calls to set methods 
  15.  */  
  16. public Builder setSingleChoiceItems(int itemsId, int checkedItem,   
  17.         final OnClickListener listener) {  
  18.     P.mItems = P.mContext.getResources().getTextArray(itemsId);  
  19.     P.mOnClickListener = listener;  
  20.     P.mCheckedItem = checkedItem;  
  21.     P.mIsSingleChoice = true;  
  22.     return this;  
  23. }  
  24.   
  25. /** 
  26.  * Set a list of items to be displayed in the dialog as the content, you will be notified of 
  27.  * the selected item via the supplied listener. The list will have a check mark displayed to 
  28.  * the right of the text for the checked item. Clicking on an item in the list will not 
  29.  * dismiss the dialog. Clicking on a button will dismiss the dialog. 
  30.  *  
  31.  * @param cursor the cursor to retrieve the items from. 
  32.  * @param checkedItem specifies which item is checked. If -1 no items are checked. 
  33.  * @param labelColumn The column name on the cursor containing the string to display in the 
  34.  *        label. 
  35.  * @param listener notified when an item on the list is clicked. The dialog will not be 
  36.  *        dismissed when an item is clicked. It will only be dismissed if clicked on a 
  37.  *        button, if no buttons are supplied it's up to the user to dismiss the dialog. 
  38.  * 
  39.  * @return This Builder object to allow for chaining of calls to set methods 
  40.  */  
  41. public Builder setSingleChoiceItems(Cursor cursor, int checkedItem, String labelColumn,   
  42.         final OnClickListener listener) {  
  43.     P.mCursor = cursor;  
  44.     P.mOnClickListener = listener;  
  45.     P.mCheckedItem = checkedItem;  
  46.     P.mLabelColumn = labelColumn;  
  47.     P.mIsSingleChoice = true;  
  48.     return this;  
  49. }  
  50.   
  51. /** 
  52.  * Set a list of items to be displayed in the dialog as the content, you will be notified of 
  53.  * the selected item via the supplied listener. The list will have a check mark displayed to 
  54.  * the right of the text for the checked item. Clicking on an item in the list will not 
  55.  * dismiss the dialog. Clicking on a button will dismiss the dialog. 
  56.  *  
  57.  * @param items the items to be displayed. 
  58.  * @param checkedItem specifies which item is checked. If -1 no items are checked. 
  59.  * @param listener notified when an item on the list is clicked. The dialog will not be 
  60.  *        dismissed when an item is clicked. It will only be dismissed if clicked on a 
  61.  *        button, if no buttons are supplied it's up to the user to dismiss the dialog. 
  62.  * 
  63.  * @return This Builder object to allow for chaining of calls to set methods 
  64.  */  
  65. public Builder setSingleChoiceItems(CharSequence[] items, int checkedItem, final OnClickListener listener) {  
  66.     P.mItems = items;  
  67.     P.mOnClickListener = listener;  
  68.     P.mCheckedItem = checkedItem;  
  69.     P.mIsSingleChoice = true;  
  70.     return this;  
  71. }   
  72.   
  73. /** 
  74.  * Set a list of items to be displayed in the dialog as the content, you will be notified of 
  75.  * the selected item via the supplied listener. The list will have a check mark displayed to 
  76.  * the right of the text for the checked item. Clicking on an item in the list will not 
  77.  * dismiss the dialog. Clicking on a button will dismiss the dialog. 
  78.  *  
  79.  * @param adapter The {@link ListAdapter} to supply the list of items 
  80.  * @param checkedItem specifies which item is checked. If -1 no items are checked. 
  81.  * @param listener notified when an item on the list is clicked. The dialog will not be 
  82.  *        dismissed when an item is clicked. It will only be dismissed if clicked on a 
  83.  *        button, if no buttons are supplied it's up to the user to dismiss the dialog. 
  84.  * 
  85.  * @return This Builder object to allow for chaining of calls to set methods 
  86.  */  
  87. public Builder setSingleChoiceItems(ListAdapter adapter, int checkedItem, final OnClickListener listener) {  
  88.     P.mAdapter = adapter;  
  89.     P.mOnClickListener = listener;  
  90.     P.mCheckedItem = checkedItem;  
  91.     P.mIsSingleChoice = true;  
  92.     return this;  
  93. }  

设置一个含有单选列表的Dialog。设置一个单选监听,当item被选中时,监听回调会被触发。当item被点击的时候,dialog并不会消失,只有Button点击时,dialog才会消失,如果没有button,只能用户自己取消dialog。

[java]  view plain copy
  1. /** 
  2.  * Sets a listener to be invoked when an item in the list is selected. 
  3.  *  
  4.  * @param listener The listener to be invoked. 
  5.  * @see AdapterView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener) 
  6.  * 
  7.  * @return This Builder object to allow for chaining of calls to set methods 
  8.  */  
  9. public Builder setOnItemSelectedListener(final AdapterView.OnItemSelectedListener listener) {  
  10.     P.mOnItemSelectedListener = listener;  
  11.     return this;  
  12. }  

设置列表item被点击时的回调监听。

[java]  view plain copy
  1. /** 
  2.          * Set a custom view to be the contents of the Dialog. If the supplied view is an instance 
  3.          * of a {@link ListView} the light background will be used. 
  4.          * 
  5.          * @param view The view to use as the contents of the Dialog. 
  6.          *  
  7.          * @return This Builder object to allow for chaining of calls to set methods 
  8.          */  
  9.         public Builder setView(View view) {  
  10.             P.mView = view;  
  11.             P.mViewSpacingSpecified = false;  
  12.             return this;  
  13.         }  
  14.           
  15.         /** 
  16.          * Set a custom view to be the contents of the Dialog, specifying the 
  17.          * spacing to appear around that view. If the supplied view is an 
  18.          * instance of a {@link ListView} the light background will be used. 
  19.          *  
  20.          * @param view The view to use as the contents of the Dialog. 
  21.          * @param viewSpacingLeft Spacing between the left edge of the view and 
  22.          *        the dialog frame 
  23.          * @param viewSpacingTop Spacing between the top edge of the view and 
  24.          *        the dialog frame 
  25.          * @param viewSpacingRight Spacing between the right edge of the view 
  26.          *        and the dialog frame 
  27.          * @param viewSpacingBottom Spacing between the bottom edge of the view 
  28.          *        and the dialog frame 
  29.          * @return This Builder object to allow for chaining of calls to set 
  30.          *         methods 
  31.          *          
  32.          *  
  33.          * This is currently hidden because it seems like people should just 
  34.          * be able to put padding around the view. 
  35.          * @hide 
  36.          */  
  37.         public Builder setView(View view, int viewSpacingLeft, int viewSpacingTop,  
  38.                 int viewSpacingRight, int viewSpacingBottom) {  
  39.             P.mView = view;  
  40.             P.mViewSpacingSpecified = true;  
  41.             P.mViewSpacingLeft = viewSpacingLeft;  
  42.             P.mViewSpacingTop = viewSpacingTop;  
  43.             P.mViewSpacingRight = viewSpacingRight;  
  44.             P.mViewSpacingBottom = viewSpacingBottom;  
  45.             return this;  
  46.         }  

为dialog设置一个自定义的View作为显示内容。

[java]  view plain copy
  1. /** 
  2.          * Sets the Dialog to use the inverse background, regardless of what the 
  3.          * contents is. 
  4.          *  
  5.          * @param useInverseBackground Whether to use the inverse background 
  6.          *  
  7.          * @return This Builder object to allow for chaining of calls to set methods 
  8.          */  
  9.         public Builder setInverseBackgroundForced(boolean useInverseBackground) {  
  10.             P.mForceInverseBackground = useInverseBackground;  
  11.             return this;  
  12.         }  

设置对话框后面的窗体是否能够获得焦点(能不能响应用户操作触发的事件)<span style="font-family: System; color: rgb(43, 43, 43); line-height: 27px; background-color: rgb(250, 250, 250);">。</span>

[java]  view plain copy
  1. /** 
  2.          * @hide 
  3.          */  
  4.         public Builder setRecycleOnMeasureEnabled(boolean enabled) {  
  5.             P.mRecycleOnMeasure = enabled;  
  6.             return this;  
  7.         }  

设置是OnMeasure后否回收视图。

[java]  view plain copy
  1. /** 
  2.   * Creates a {@link AlertDialog} with the arguments supplied to this builder. It does not 
  3.   * {@link Dialog#show()} the dialog. This allows the user to do any extra processing 
  4.   * before displaying the dialog. Use {@link #show()} if you don't have any other processing 
  5.   * to do and want this to be created and displayed. 
  6.   */  
  7.  public AlertDialog create() {  
  8.      final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);  
  9.      P.apply(dialog.mAlert);  
  10.      dialog.setCancelable(P.mCancelable);  
  11.      if (P.mCancelable) {  
  12.          dialog.setCanceledOnTouchOutside(true);  
  13.      }  
  14.      dialog.setOnCancelListener(P.mOnCancelListener);  
  15.      if (P.mOnKeyListener != null) {  
  16.          dialog.setOnKeyListener(P.mOnKeyListener);  
  17.      }  
  18.      return dialog;  
  19.  }  

创建一个dialog,这时dialog并没有显示出来。我们在外面不能通过new来实例化一个AlertDialog,只能通过Builder类的create来创建一个AlertDialog。

最后一个方法,显示dialog:

[java]  view plain copy
  1. /** 
  2.  * Creates a {@link AlertDialog} with the arguments supplied to this builder and 
  3.  * {@link Dialog#show()}'s the dialog. 
  4.  */  
  5. public AlertDialog show() {  
  6.     AlertDialog dialog = create();  
  7.     dialog.show();  
  8.     return dialog;  
  9. }  

你可能感兴趣的:(AlertDialog源码解析)