|
Android 对话框支持自定义标题,内容,按钮和点击事件,基本上可以满足我们日常的使用。 但有时候我们想要修改对话框的文字,按钮颜色等,系统并没有提供对应的方法,正常情况下只能自定义布局。 接下来通过源码解析介绍几种修改 Dialog样式的方法。
/ f) G& o9 a* g/ X3 W r: m一、Dialog源码解析3 U3 E4 y) c M4 O L u! V
1.1 new AlertDialog.Builder(this).create()& c4 p9 R1 P! }
- protected AlertDialog(@NonNull Context context, @StyleRes int themeResId) {
- super(context, resolveDialogTheme(context, themeResId));
- //创建AlertController,是Dialog布局相关代码
- mAlert = new AlertController(getContext(), this, getWindow());
- }
-
- @NonNull
- public AlertDialog create() {
- // We can't use Dialog's 3-arg constructor with the createThemeContextWrapper param,
- // so we always have to re-set the theme
- final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
- 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;
- }
-
- 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);
- }
- ..........
- AlertDialog 构造函数中会创建 AlertController,用来控制对话框的布局
- P.apply(dialog.mAlert); 将用户自定义的配置赋值给 AlertController
$ v/ S _+ w: ^$ f0 ^ 1.2 AlertController) m; |: T4 a5 F3 x. M
- public AlertController(Context context, AppCompatDialog di, Window window) {
- mContext = context;
- mDialog = di;
- mWindow = window;
- mHandler = new ButtonHandler(di);
-
- final TypedArray a = context.obtainStyledAttributes(null, R.styleable.AlertDialog,
- R.attr.alertDialogStyle, 0);
-
- mAlertDialogLayout = a.getResourceId(R.styleable.AlertDialog_android_layout, 0);
- mButtonPanelSideLayout = a.getResourceId(R.styleable.AlertDialog_buttonPanelSideLayout, 0);
-
- mListLayout = a.getResourceId(R.styleable.AlertDialog_listLayout, 0);
- mMultiChoiceItemLayout = a.getResourceId(R.styleable.AlertDialog_multiChoiceItemLayout, 0);
- mSingleChoiceItemLayout = a
- .getResourceId(R.styleable.AlertDialog_singleChoiceItemLayout, 0);
- mListItemLayout = a.getResourceId(R.styleable.AlertDialog_listItemLayout, 0);
- mShowTitle = a.getBoolean(R.styleable.AlertDialog_showTitle, true);
- mButtonIconDimen = a.getDimensionPixelSize(R.styleable.AlertDialog_buttonIconDimen, 0);
-
- a.recycle();
-
- /* We use a custom title so never request a window title */
- di.supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
- }
R.attr.alertDialogStyle 是对话框的默认样式 , ]5 Z2 c; z, J8 }& Y0 K( j* D1 S* t
- <item name="alertDialogStyle">@style/AlertDialog.AppCompat</item>
- <style name="AlertDialog.AppCompat" parent="Base.AlertDialog.AppCompat"/>
- <style name="Base.AlertDialog.AppCompat" parent="android:Widget">
- <item name="android:layout">@layout/abc_alert_dialog_material</item>
- <item name="listLayout">@layout/abc_select_dialog_material</item>
- <item name="listItemLayout">@layout/select_dialog_item_material</item>
- <item name="multiChoiceItemLayout">@layout/select_dialog_multichoice_material</item>
- <item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_material</item>
- <item name="buttonIconDimen">@dimen/abc_alert_dialog_button_dimen</item>
- </style>
上述代码可以看出,abc_alert_dialog_material 就是dialog的默认布局。
6 I6 Y. S2 [, D9 R1 }! k6 \- <androidx.appcompat.widget.AlertDialogLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/parentPanel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start|left|top"
- android:orientation="vertical">
-
- <include layout="@layout/abc_alert_dialog_title_material"/>
-
- <FrameLayout
- android:id="@+id/contentPanel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="48dp">
-
- <View android:id="@+id/scrollIndicatorUp"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_gravity="top"
- android:background="?attr/colorControlHighlight"
- android:visibility="gone"/>
-
- <androidx.core.widget.NestedScrollView
- android:id="@+id/scrollView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipToPadding="false">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <android.widget.Space
- android:id="@+id/textSpacerNoTitle"
- android:layout_width="match_parent"
- android:layout_height="@dimen/abc_dialog_padding_top_material"
- android:visibility="gone"/>
-
- <TextView
- android:id="@android:id/message"
- style="@style/TextAppearance.AppCompat.Subhead"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="?attr/dialogPreferredPadding"
- android:paddingRight="?attr/dialogPreferredPadding"/>
-
- <android.widget.Space
- android:id="@+id/textSpacerNoButtons"
- android:layout_width="match_parent"
- android:layout_height="@dimen/abc_dialog_padding_top_material"
- android:visibility="gone"/>
- </LinearLayout>
- </androidx.core.widget.NestedScrollView>
-
- <View android:id="@+id/scrollIndicatorDown"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_gravity="bottom"
- android:background="?attr/colorControlHighlight"
- android:visibility="gone"/>
-
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/customPanel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="48dp">
-
- <FrameLayout
- android:id="@+id/custom"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- </FrameLayout>
-
- <include layout="@layout/abc_alert_dialog_button_bar_material"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
- </androidx.appcompat.widget.AlertDialogLayout>
标题布局:
, \7 B6 D. D/ m; | |
|