it-swarm.cn

如何更改AlertDialog的主题

我想知道是否有人可以帮助我。我正在尝试创建自定义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位于drawable文件夹中。这也可以在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。任何人都可以帮我解决这个问题吗?

214
Min Soo Kim

在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>
338
Arve Waltin

我正在使用sdk 1.6来解决这个与AlertDialog主题相关的问题,如下所述: http://markmail.org/message/mj5ut56irkrkc4nr

我通过以下方式解决了这个问题:

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

希望这可以帮助。

89
chee

我在我的博客中写了一篇关于如何使用XML样式文件配置AlertDialog布局的 article 。主要问题是您需要为不同的布局参数设置不同的样式。这是一个基于AlertDialog风格的Holo Light Platform版本19的样板文件的样板文件,应该涵盖一系列标准布局方面,如文本大小和背景颜色。

<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>
61
Nantoka

我正在努力解决这个问题 - 您可以在主题中使用Android:alertDialogStyle="@style/AlertDialog"设置对话框的背景,但它会忽略您拥有的任何文本设置。正如@rflexor上面所述,在Honeycomb之前无法使用SDK(你可以使用Reflection)。

简而言之,我的解决方案是使用上面的方式设置对话框的背景,然后设置自定义标题和内容视图(使用与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来创建对话框,并像往常一样调用setTitlesetMessage

31
Joseph Earl
 <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();
26
saigopi

您可以在启动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>
19
pha

我想这不可能。至少不与Builder一起使用。我正在使用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);
    [...]
}

builder只是不打电话。

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

8
rflexor

更好的方法使用自定义对话框并根据您的需要自定义这里是自定义对话框示例.....

enter image description here

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>
4
user2671902

对于自定义对话框:

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

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


对于AlertDialog:

只需使用以下构造函数创建alertDialog:

 new AlertDialog.Builder(
 new ContextThemeWrapper(context, Android.R.style.Theme_Dialog))
4
Amir Hossein Ghasemi

任何试图在片段中执行此操作的人(使用支持库,即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给了我Nudge来扩展AlertDialog并公开构造函数谢谢

3
Blundell

Arve Waltin的解决方案看起来很不错,虽然我还没有测试过。还有另一种解决方案,以防你无法正常工作....扩展AlertDialog.Builder并覆盖所有方法(例如setTextsetTitlesetView等),不设置实际的Dialog的文本/标题/视图,而是创建对话框视图中的新视图可以完成所有内容。然后你随心所欲地设计一切。

为了澄清,就父类而言,View已设置,而没有其他任何内容。

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

2
Steven L

它可以通过使用Builder的setView()完成。您可以创建自己选择的任何视图并将其输入构建器。这很好用。我使用由对话框构建器呈现的自定义TextView。我没有设置消息,这个空间用于呈现我的客户textview。

0
AKh