How to change theme for AlertDialog

2018-12-31 08:17发布

I was wondering if someone could help me out. I am trying to create a custom AlertDialog. In order to do this, I added the following line of code in 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 is located in drawable folder. This is also available in Android SDK res folder.

The following is the main activity.

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();
    }
}

In order to apply the theme to an AlertDialog, I had to set the theme to the current context.

However, I just can't seem to get the app to show customized AlertDialog. Can anyone help me out with this?

13条回答
牵手、夕阳
2楼-- · 2018-12-31 08:44

For Custom Dialog:

just call super(context,R.style.<dialog style>) instead of super(context) in dialog constructor

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


For AlertDialog:

Just create alertDialog with this constructor:

 new AlertDialog.Builder(
 new ContextThemeWrapper(context, android.R.style.Theme_Dialog))
查看更多
美炸的是我
3楼-- · 2018-12-31 08:44

Anyone trying to do this within a Fragment (using the support library i.e. pre API 11) should go with this:

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 gave me the nudge to extend AlertDialog and expose the constructor thanks

查看更多
忆尘夕之涩
4楼-- · 2018-12-31 08:50

I guess it cannot be done. At least not with the Builder. I'm working with 1.6 and the Implementation in Builder.create() is:

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

which calls the "not-theme-aware" constructor of AlertDialog, which looks like this:

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

There is a second constructor in AlertDialog for changing themes:

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

that the Builder just doesn't call.

If the Dialog is pretty generic anyway, I'd try writing a subclass of AlertDialog, calling the second constructor and use that class instead of the Builder-mechanism.

查看更多
笑指拈花
5楼-- · 2018-12-31 08:54

It can done simply by using the Builder's setView(). You can create any view of your choice and feed into the builder. This works good. I use a custom TextView that is rendered by the dialog builder. I dont set the message and this space is utilized to render my custome textview.

查看更多
唯独是你
6楼-- · 2018-12-31 08:55

I have written an article in my blog on how to configure the layout of an AlertDialog with XML style files. The main problem is that you need different style definitions for different layout parameters. Here is a boilerplate based on the AlertDialog style of Holo Light Platform version 19 for a style file that should cover a bunch of the standard layout aspects like text sizes and background colors.

<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>
查看更多
只若初见
7楼-- · 2018-12-31 08:56

In Dialog.java (Android src) a ContextThemeWrapper is used. So you could copy the idea and do something like:

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

And then style it like you want:

<?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>
查看更多
登录 后发表回答