Android修改Dialog樣式的方法
一、Dialog源碼解析
1.1 new AlertDialog.Builder(this).create()
protected AlertDialog(@NonNull Context context, @StyleRes int themeResId) {
super(context, resolveDialogTheme(context, themeResId));
//創(chuàng)建AlertController,是Dialog布局相關(guān)代碼
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 構(gòu)造函數(shù)中會創(chuàng)建 AlertController,用來控制對話框的布局
- P.apply(dialog.mAlert); 將用戶自定義的配置賦值給 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 是 對話框的默認(rèn)樣式,
<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的默認(rèn)布局。
<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>
標(biāo)題布局:
<!-- 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>
按鈕布局:
<!-- 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>
二、修改Dialog樣式
2.1 通過findViewById
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(msg);
builder.setPositiveButton(getString(R.string.yes), null);
AlertDialog dialog = builder.create();
dialog.show();
//直接通過id找到對應(yīng)的控件
Button button = dialog.findViewById(android.R.id.button1);
//或者通過getButton方法也可以獲取到
Button button2 = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
這種修改方式必須在 show() 之后調(diào)用,否則會出現(xiàn)空指針異常。這個是因為,執(zhí)行 show() 方法的時候,dialog才會初始化布局,具體源碼可以查看 Dialog 的 onCreate 方法。
2.2 自定義style
通過上面源碼可以發(fā)現(xiàn),Dialog三個按鈕的樣式如下:
- 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"/>
自定義樣式替換上述 style即可達到修改效果。
在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>
<!-- 彈出框樣式 -->
<style name="testDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="buttonBarPositiveButtonStyle">@style/accessPositiveBtnStyle</item>
<item name="buttonBarNegativeButtonStyle">@style/accessNegativeBtnStyle</item>
</style>
具體使用:
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.testDialogTheme);
builder.setMessage("Test");
builder.setCancelable(false);
builder.setPositiveButton("確認(rèn)", null);
builder.setNegativeButton("取消", null);
Dialog dialog = builder.create();
dialog.show();
以上就是Android修改Dialog樣式的方法的詳細(xì)內(nèi)容,更多關(guān)于Android修改Dialog樣式的資料請關(guān)注腳本之家其它相關(guān)文章!
- android dialog根據(jù)彈窗等級排序顯示的示例代碼
- Android自定義Dialog原理實例解析
- Android 自定義加載動畫Dialog彈窗效果的示例代碼
- android BottomSheetDialog新控件解析實現(xiàn)知乎評論列表效果(實例代碼)
- Android 之BottomsheetDialogFragment仿抖音評論底部彈出對話框效果(實例代碼)
- Android ProgressDialog用法之實現(xiàn)app上傳文件進度條轉(zhuǎn)圈效果
- Android自定義底部彈出框ButtomDialog
- Android中AlertDialog四種對話框的最科學(xué)編寫用法(實例代碼)
- 詳解Android 8.1.0 Service 中 彈出 Dialog的方法
- Android 彈出Dialog時隱藏狀態(tài)欄和底部導(dǎo)航欄的方法
- Android彈出DatePickerDialog并獲取值的方法
- Android開發(fā)之DatePickerDialog、TimePickerDialog時間日期對話框用法示例
相關(guān)文章
基于Android studio3.6的JNI教程之ncnn之語義分割ENet
這篇文章主要介紹了基于Android studio3.6的JNI教程之ncnn之語義分割ENet的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值 ,需要的朋友可以參考下2020-03-03
解決android6.0以上不能讀取外部存儲權(quán)限的問題
今天小編就為大家分享一篇解決android6.0以上不能讀取外部存儲權(quán)限的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
android10 隱藏SystemUI鎖屏下的多用戶圖標(biāo)的示例代碼
這篇文章主要介紹了android10 隱藏SystemUI鎖屏下的多用戶圖標(biāo),本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
Android修改源碼解決Alertdialog觸摸對話框邊緣消失的問題
在開發(fā)的時候遇到一個問題,就是一觸摸對話框邊緣外部,對話框會自動消失。這個問題很糾結(jié)啊,查找了一下發(fā)現(xiàn)從Android 4.0開始,AlertDialog有了變化,就是在觸摸對話框邊緣外部,對話框會自動消失,查了源碼,找到解決辦法如下2013-11-11
Android實現(xiàn)網(wǎng)絡(luò)多線程文件下載
這篇文章主要介紹了Android實現(xiàn)網(wǎng)絡(luò)多線程文件下載的相關(guān)資料,需要的朋友可以參考下2016-03-03

