如何更改AlertDialog的主题

我想知道如果有人能帮助我。 我正在尝试创build一个自定义AlertDialog。 为了做到这一点,我在styles.xml中添加了以下代码行

<resources> <style name="CustomAlertDialog" parent="android:Theme.Dialog.Alert"> <item name="android:windowBackground">@drawable/color_panel_background</item> </style> </resources> 
  • color_panel_background.9.png位于可绘制文件夹中。 这也在Android SDK res文件夹中可用。

以下是主要活动。

 package com.customdialog; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; public class CustomDialog extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.setTheme(R.style.CustomAlertDialog); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("HELLO!"); builder .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { //MyActivity.this.finish(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { //dialog.cancel(); } }); AlertDialog alertdialog = builder.create(); alertdialog.show(); } } 

为了将主题应用于AlertDialog,我必须将主题设置为当前上下文。

不过,我似乎无法让应用程序显示自定义AlertDialog。 任何人都可以帮我解决这个问题吗?

在Dialog.java(Android src)中使用ContextThemeWrapper。 所以你可以复制这个想法,做一些事情:

AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AlertDialogCustom));

然后像你想要的样式:

 <?xml version="1.0" encoding="utf-8"?> <resources> <style name="AlertDialogCustom" parent="@android:style/Theme.Dialog"> <item name="android:textColor">#00FF00</item> <item name="android:typeface">monospace</item> <item name="android:textSize">10sp</item> </style> </resources> 

我有这个AlertDialog主题相关的问题使用sdk 1.6在这里描述: http : AlertDialog

我通过执行以下操作来解决问题:

  new AlertDialog.Builder( new ContextThemeWrapper(context, android.R.style.Theme_Dialog)) 

希望这可以帮助。

我在博客中写了一篇关于如何用XML样式文件configurationAlertDialog布局的文章。 主要的问题是你需要不同的风格定义不同的布局参数。 这是一个基于Holo Light Platform 19版本的AlertDialog风格的样板文件,它应该涵盖一些标准的布局方面,如文本大小和背景颜色。

 <style name="AppBaseTheme" parent="android:Theme.Holo.Light"> ... <item name="android:alertDialogTheme">@style/MyAlertDialogTheme</item> <item name="android:alertDialogStyle">@style/MyAlertDialogStyle</item> ... </style> <style name="MyBorderlessButton"> <!-- Set background drawable and text size of the buttons here --> <item name="android:background">...</item> <item name="android:textSize">...</item> </style> <style name="MyButtonBar"> <!-- Define a background for the button bar and a divider between the buttons here --> <item name="android:divider">....</item> <item name="android:dividerPadding">...</item> <item name="android:showDividers">...</item> <item name="android:background">...</item> </style> <style name="MyAlertDialogTitle"> <item name="android:maxLines">1</item> <item name="android:scrollHorizontally">true</item> </style> <style name="MyAlertTextAppearance"> <!-- Set text size and color of title and message here --> <item name="android:textSize"> ... </item> <item name="android:textColor">...</item> </style> <style name="MyAlertDialogTheme"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowTitleStyle">@style/MyAlertDialogTitle</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item> <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item> <item name="android:windowIsFloating">true</item> <item name="android:textAppearanceMedium">@style/MyAlertTextAppearance</item> <!-- If you don't want your own button bar style use @android:style/Holo.Light.ButtonBar.AlertDialog and ?android:attr/borderlessButtonStyle instead of @style/MyButtonBar and @style/MyBorderlessButton --> <item name="android:buttonBarStyle">@style/MyButtonBar</item> <item name="android:buttonBarButtonStyle">@style/MyBorderlessButton</item> </style> <style name="MyAlertDialogStyle"> <!-- Define background colors of title, message, buttons, etc. here --> <item name="android:fullDark">...</item> <item name="android:topDark">...</item> <item name="android:centerDark">...</item> <item name="android:bottomDark">...</item> <item name="android:fullBright">...</item> <item name="android:topBright">...</item> <item name="android:centerBright">...</item> <item name="android:bottomBright">...</item> <item name="android:bottomMedium">...</item> <item name="android:centerMedium">...</item> </style> 

我一直在努力 – 你可以在主题中使用android:alertDialogStyle="@style/AlertDialog"设置对话框的背景android:alertDialogStyle="@style/AlertDialog" ,但是它会忽略任何你有的文本设置。 正如@rflexor上面所说的,在Honeycomb之前不能用SDK来完成(可以使用Reflection )。

简而言之,我的解决scheme是使用上面的样式设置对话框的背景,然后设置自定义标题和内容视图(使用与SDK中的布局相同的布局)。

我的包装:

 import com.mypackage.R; import android.app.AlertDialog; import android.content.Context; import android.graphics.drawable.Drawable; import android.view.View; import android.widget.ImageView; import android.widget.TextView; public class CustomAlertDialogBuilder extends AlertDialog.Builder { private final Context mContext; private TextView mTitle; private ImageView mIcon; private TextView mMessage; public CustomAlertDialogBuilder(Context context) { super(context); mContext = context; View customTitle = View.inflate(mContext, R.layout.alert_dialog_title, null); mTitle = (TextView) customTitle.findViewById(R.id.alertTitle); mIcon = (ImageView) customTitle.findViewById(R.id.icon); setCustomTitle(customTitle); View customMessage = View.inflate(mContext, R.layout.alert_dialog_message, null); mMessage = (TextView) customMessage.findViewById(R.id.message); setView(customMessage); } @Override public CustomAlertDialogBuilder setTitle(int textResId) { mTitle.setText(textResId); return this; } @Override public CustomAlertDialogBuilder setTitle(CharSequence text) { mTitle.setText(text); return this; } @Override public CustomAlertDialogBuilder setMessage(int textResId) { mMessage.setText(textResId); return this; } @Override public CustomAlertDialogBuilder setMessage(CharSequence text) { mMessage.setText(text); return this; } @Override public CustomAlertDialogBuilder setIcon(int drawableResId) { mIcon.setImageResource(drawableResId); return this; } @Override public CustomAlertDialogBuilder setIcon(Drawable icon) { mIcon.setImageDrawable(icon); return this; } } 

alert_dialog_title.xml(取自SDK)

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <LinearLayout android:id="@+id/title_template" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" android:layout_marginTop="6dip" android:layout_marginBottom="9dip" android:layout_marginLeft="10dip" android:layout_marginRight="10dip"> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" android:paddingTop="6dip" android:paddingRight="10dip" android:src="@drawable/ic_dialog_alert" /> <TextView android:id="@+id/alertTitle" style="@style/?android:attr/textAppearanceLarge" android:singleLine="true" android:ellipsize="end" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> <ImageView android:id="@+id/titleDivider" android:layout_width="fill_parent" android:layout_height="1dip" android:scaleType="fitXY" android:gravity="fill_horizontal" android:src="@drawable/divider_horizontal_bright" /> </LinearLayout> 

alert_dialog_message.xml

 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scrollView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingTop="2dip" android:paddingBottom="12dip" android:paddingLeft="14dip" android:paddingRight="10dip"> <TextView android:id="@+id/message" style="?android:attr/textAppearanceMedium" android:textColor="@color/dark_grey" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dip" /> </ScrollView> 

然后,只需使用CustomAlertDialogBuilder而不是AlertDialog.Builder创build对话框,然后像往常一样调用setTitlesetMessage

  <style name="AlertDialogCustom" parent="Theme.AppCompat.Light.Dialog.Alert"> <!-- Used for the buttons --> <item name="colorAccent">@color/colorAccent</item> <!-- Used for the title and text --> <item name="android:textColorPrimary">#FFFFFF</item> <!-- Used for the background --> <item name="android:background">@color/teal</item> </style> new AlertDialog.Builder(new ContextThemeWrapper(context,R.style.AlertDialogCustom)) .setMessage(Html.fromHtml(Msg)) .setPositiveButton(posBtn, okListener) .setNegativeButton(negBtn, null) .create() .show(); 

我想这是不能做的。 至less没有与build设者。 我正在使用1.6和Builder.create()中的实现是:

 public AlertDialog create() { final AlertDialog dialog = new AlertDialog(P.mContext); P.apply(dialog.mAlert); [...] } 

它调用AlertDialog的“not-theme-aware”构造函数,如下所示:

 protected AlertDialog(Context context) { this(context, com.android.internal.R.style.Theme_Dialog_Alert); } 

AlertDialog中有第二个构造函数用于更改主题:

 protected AlertDialog(Context context, int theme) { super(context, theme); [...] } 

build设者只是不打电话。

如果对话是非常通用的,我会尝试编写AlertDialog的子类,调用第二个构造函数,并使用该类而不是Builder-mechanism。

启动Builder时可以直接指定一个主题:

 AlertDialog.Builder builder = new AlertDialog.Builder( getActivity(), R.style.MyAlertDialogTheme); 

然后在你的values/styles.xml自定义你的主题

 <!-- Alert Dialog --> <style name="MyAlertDialogTheme" parent="Theme.AppCompat.Dialog.Alert"> <item name="colorAccent">@color/colorAccent</item> <item name="android:colorBackground">@color/alertDialogBackground</item> <item name="android:windowBackground">@color/alertDialogBackground</item> </style> 

更好的方法来做到这一点使用自定义对话框,并根据您的需求定制这里是自定义对话框的例子

在这里输入图像描述

 public class CustomDialogUI { Dialog dialog; Vibrator vib; RelativeLayout rl; @SuppressWarnings("static-access") public void dialog(final Context context, String title, String message, final Runnable task) { dialog = new Dialog(context); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom); dialog.setCancelable(false); TextView m = (TextView) dialog.findViewById(R.id.message); TextView t = (TextView) dialog.findViewById(R.id.title); final Button n = (Button) dialog.findViewById(R.id.button2); final Button p = (Button) dialog.findViewById(R.id.next_button); rl = (RelativeLayout) dialog.findViewById(R.id.rlmain); t.setText(bold(title)); m.setText(message); dialog.show(); n.setText(bold("Close")); p.setText(bold("Ok")); // color(context,rl); vib = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE); n.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { vib.vibrate(15); dialog.dismiss(); } }); p.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { vib.vibrate(20); dialog.dismiss(); task.run(); } }); } //customize text style bold italic.... public SpannableString bold(String s) { SpannableString spanString = new SpannableString(s); spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, spanString.length(), 0); spanString.setSpan(new UnderlineSpan(), 0, spanString.length(), 0); // spanString.setSpan(new StyleSpan(Typeface.ITALIC), 0, // spanString.length(), 0); return spanString; } 

}

这里是xml布局

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00000000" > <RelativeLayout android:id="@+id/rlmain" android:layout_width="fill_parent" android:layout_height="150dip" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:background="#569CE3" > <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginLeft="25dip" android:layout_marginTop="10dip" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="Are you Sure?" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="#ffffff" android:textSize="13dip" /> </RelativeLayout> <RelativeLayout android:id="@+id/relativeLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/relativeLayout1" android:layout_alignRight="@+id/relativeLayout1" android:layout_below="@+id/relativeLayout1" android:layout_marginTop="5dip" > </RelativeLayout> <ProgressBar android:id="@+id/process" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="3dip" android:layout_marginTop="3dip" /> <RelativeLayout android:id="@+id/relativeLayout3" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/relativeLayout2" android:layout_below="@+id/relativeLayout2" android:layout_toLeftOf="@+id/process" > <TextView android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:text="Medium Text" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="#ffffff" android:textSize="13dip"/> </RelativeLayout> <Button android:id="@+id/next_button" android:layout_width="90dip" android:layout_height="35dip" android:layout_alignParentBottom="true" android:textColor="@drawable/button_text_color" android:background="@drawable/blue_button" android:layout_marginBottom="5dp" android:textSize="10dp" android:layout_alignRight="@+id/relativeLayout3" android:text="Okay" /> <Button android:id="@+id/button2" android:text="Cancel" android:textColor="@drawable/button_text_color" android:layout_width="90dip" android:layout_height="35dip" android:layout_marginBottom="5dp" android:background="@drawable/blue_button" android:layout_marginRight="7dp" android:textSize="10dp" android:layout_alignParentBottom="true" android:layout_toLeftOf="@+id/next_button" /> </RelativeLayout> 

任何人在片段内(使用支持库,即预先API 11)都应该这样做:

 public class LoadingDialogFragment extends DialogFragment { public static final String ID = "loadingDialog"; public static LoadingDialogFragment newInstance() { LoadingDialogFragment f = new LoadingDialogFragment(); return f; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { StyleAlertDialog adb = new StyleAlertDialog(getActivity(), R.style.Your_Style); adb.setView(getActivity().getLayoutInflater().inflate(R.layout.fragment_dialog_layout, null)); return adb; } private class StyleAlertDialog extends AlertDialog { protected StyleAlertDialog(Context context, int theme) { super(context, theme); } } } 

@Rflexor给了我微调延长AlertDialog和暴露的构造函数谢谢

沃尔丁的解决scheme看起来不错,虽然我还没有testing过。 还有另一种解决scheme,如果你有麻烦得到这个工作….扩展AlertDialog.Builder和重写所有的方法(如setTextsetTitlesetView等),不设置实际的对话框的文本/标题/视图,但在Dialog的View中创build一个新的视图。 那么你可以随心所欲地devise任何样式。

为了澄清,就父母而言,视图是设置的,没有别的。

就您的自定义扩展类而言,一切都是在该视图内完成的。

它可以简单地通过使用Builder的setView()来完成。 您可以创build任何您select的视图,然后input到构build器中。 这很好。 我使用由对话框构build器呈现的自定义TextView。 我不设置消息,这个空间是用来呈现我自己的文本视图。

对于自定义对话框:

只需在对话框构造函数中调用super(context,R.style.<dialog style>)而不是super(context)

 public class MyDialog extends Dialog { public MyDialog(Context context) { super(context,R.style.R.style.Theme_AppCompat_Light_Dialog_Alert) } } 

对于AlertDialog:

用这个构造函数创buildalertDialog:

  new AlertDialog.Builder( new ContextThemeWrapper(context, android.R.style.Theme_Dialog))