Android Method for Modifying Dialog Style
- 2021-12-12 09:57:56
- OfStack
1. Dialog source code analysis
1.1 new AlertDialog.Builder(this).create()
protected AlertDialog(@NonNull Context context, @StyleRes int themeResId) {
super(context, resolveDialogTheme(context, themeResId));
// Create AlertController Yes Dialog Layout related codes
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);
}
..........
AlertController is created in the AlertDialog constructor to control the layout of the dialog box
P. apply (dialog. mAlert); Assign user-defined configuration to AlertController
1.2 AlertController
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 is the default style for dialog boxes,
<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>
As you can see from the above code, abc_alert_dialog_material is the default layout for dialog.
<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>
Title layout:
<!-- abc_alert_dialog_title_material: -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- If the client uses a customTitle, it will be added here. -->
<LinearLayout
android:id="@+id/title_template"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|start|left"
android:orientation="horizontal"
android:paddingLeft="?attr/dialogPreferredPadding"
android:paddingRight="?attr/dialogPreferredPadding"
android:paddingTop="@dimen/abc_dialog_padding_top_material">
<ImageView
android:id="@android:id/icon"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_marginEnd="8dip"
android:layout_marginRight="8dip"
android:scaleType="fitCenter"
android:src="@null"/>
<androidx.appcompat.widget.DialogTitle
android:id="@+id/alertTitle"
style="?android:attr/windowTitleStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:ellipsize="end"
android:singleLine="true"
android:textAlignment="viewStart"/>
</LinearLayout>
<android.widget.Space
android:id="@+id/titleDividerNoCustom"
android:layout_width="match_parent"
android:layout_height="@dimen/abc_dialog_title_divider_material"
android:visibility="gone"/>
</LinearLayout>
Button layout:
<!-- abc_alert_dialog_button_bar_material: -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/buttonPanel"
style="?attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollIndicators="top|bottom">
<androidx.appcompat.widget.ButtonBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layoutDirection="locale"
android:orientation="horizontal"
android:paddingBottom="4dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="4dp">
<Button
android:id="@android:id/button3"
style="?attr/buttonBarNeutralButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<android.widget.Space
android:id="@+id/spacer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="invisible"/>
<Button
android:id="@android:id/button2"
style="?attr/buttonBarNegativeButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@android:id/button1"
style="?attr/buttonBarPositiveButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.appcompat.widget.ButtonBarLayout>
</ScrollView>
2. Modify the Dialog style
2.1 Through findViewById
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(msg);
builder.setPositiveButton(getString(R.string.yes), null);
AlertDialog dialog = builder.create();
dialog.show();
// Direct through id Find the corresponding control
Button button = dialog.findViewById(android.R.id.button1);
// Or through getButton Method can also get the
Button button2 = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
This modification must be called after show () or a null pointer exception will occur. This is because the execution of show () method, dialog will initialize the layout, the specific source code can see the onCreate method of Dialog.
2.2 Customize style
From the above source code, we can find that the style of Dialog3 buttons is as follows:
buttonBarNeutralButtonStyle buttonBarNegativeButtonStyle buttonBarPositiveButtonStyle
<Button
android:id="@android:id/button3"
style="?attr/buttonBarNeutralButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<android.widget.Space
android:id="@+id/spacer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="invisible"/>
<Button
android:id="@android:id/button2"
style="?attr/buttonBarNegativeButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@android:id/button1"
style="?attr/buttonBarPositiveButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
The modification effect can be achieved by replacing the above style with a custom style.
Add the following code to style. xml:
<style name="accessPositiveBtnStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textColor">@color/test1</item>
</style>
<style name="accessNegativeBtnStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textColor">@color/test2</item>
</style>
<!-- Pop-up style -->
<style name="testDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="buttonBarPositiveButtonStyle">@style/accessPositiveBtnStyle</item>
<item name="buttonBarNegativeButtonStyle">@style/accessNegativeBtnStyle</item>
</style>
Specific use:
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.testDialogTheme);
builder.setMessage("Test");
builder.setCancelable(false);
builder.setPositiveButton(" Confirm ", null);
builder.setNegativeButton(" Cancel ", null);
Dialog dialog = builder.create();
dialog.show();
The above is the Android modified Dialog style method details, more about Android modified Dialog style information please pay attention to other related articles on this site!