8

我在应用程序中有一个警报对话框,如下所示。

在此处输入图像描述

我希望标题和分隔标题的行 - 消息正文为橙色。我怎样才能做到这一点?我尝试的是使用自定义样式,如下所示。但这没有用。

<style name="AboutDialog" parent="@android:style/Theme.Dialog">
  <item name="android:textColor">#E5492A</item>
</style>

我的警报对话框代码:

AlertDialog.Builder alertDialog = new AlertDialog.Builder( new ContextThemeWrapper(MainActivity.context, R.style.AboutDialog));
alertDialog.setTitle("Sample");
        alertDialog.setMessage(R.string.rate_dialog_text);
        alertDialog.setPositiveButton(R.string.rate_now_text,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        MainActivity.context.startActivity(new Intent(
                                Intent.ACTION_VIEW, Uri
                                        .parse("market://details?id="
                                                + MainActivity.APP_PNAME)));
                        if (editor != null) {
                            editor.putBoolean("dontshowagain", true);
                            editor.commit();
                        }
                        dialog.dismiss();

                    }
                });

        alertDialog.setNeutralButton(R.string.remind_later_text,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });

        alertDialog.setNegativeButton(R.string.no_thanks_text,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        if (editor != null) {
                            editor.putBoolean("dontshowagain", true);
                            editor.commit();
                        }
                        dialog.dismiss();
                    }
                });

        return alertDialog.create();

    }
4

4 回答 4

18

代替:

AlertDialog.Builder alertDialog = new AlertDialog.Builder(
    new ContextThemeWrapper(MainActivity.context, R.style.AboutDialog));

试试这个:

AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.AboutDialog);

注意:这仅适用于 API 11 (Android 3.0) 及更高版本。

如果您需要支持 Android < 3.0,您可能必须创建一个自定义对话框(而不是使用AlertDialog

编辑添加了非常低俗的基于反射的黑客

如果您真的被卡住并且不想实现自定义对话框,请尝试以下操作。

在您构建对话框之后并且在您想要返回它之前,而不是这样:

return alertDialog.create();

做这个:

AlertDialog ad = alertDialog.create(); // Create the dialog
// Add listener so we can modify the dialog before it is shown
ad.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface dialogInterface) {
        // Set the text color on the dialog title and separator
        setTextColor(dialogInterface, 0xFFE5492A);
    }
});
return ad;

现在添加这个非常讨厌的基于反射的方法:

public void setTextColor(DialogInterface alert, int color) {
    try {
        Class c = alert.getClass();
        Field mAlert = c.getDeclaredField("mAlert");
        mAlert.setAccessible(true);
        Object alertController = mAlert.get(alert);
        c = alertController.getClass();
        Field mTitleView = c.getDeclaredField("mTitleView");
        mTitleView.setAccessible(true);
        Object dialogTitle = mTitleView.get(alertController);
        TextView dialogTitleView = (TextView)dialogTitle;
        // Set text color on the title
        dialogTitleView.setTextColor(color);
        // To find the horizontal divider, first
        //  get container around the Title
        ViewGroup parent = (ViewGroup)dialogTitleView.getParent();
        // Then get the container around that container
        parent = (ViewGroup)parent.getParent();
        for (int i = 0; i < parent.getChildCount(); i++) {
            View v = parent.getChildAt(i);
            if (v instanceof ImageView) {
                // We got an ImageView, that should be the separator
                ImageView im = (ImageView)v;
                // Set a color filter on the image
                im.setColorFilter(color);
            }
        }
    } catch (Exception e) {
        // Ignore any exceptions, either it works or it doesn't
    }
}

我在 Android 2.2 和 Android 4.0 上对此进行了测试,并且可以正常工作。它可能不完全符合您的要求,因此您需要尝试一下。我不能保证它可以在所有设备或未来版本的 Android 上运行,因为它在很大程度上取决于AlertDialog类的实现方式(如果他们在未来改变它,这可能不再适用)。

给关心的人一些注意事项:

  1. 我使用的原因是因为在它们被充气之前,setOnShowListener()您实际上无法访问使用的内部View对象。AlertDialog当您创建 时,它们不会立即膨胀AlertDialog,它会在一段时间后发生。使用监听器,我们可以在布局膨胀之后但在Dialog显示之前获得控制。

  2. 我正在使用反射来访问AlertDialog实现中的内部成员变量。一旦我可以访问TextView包含标题的内容,我必须四处寻找用于将标题与消息分开的水平线。为此,我得到Layout围绕标题的 (这Layout包含警报图标和标题文本)。然后我得到Layout围绕它的那个(这Layout包含了图标、标题文本和分隔符)。然后我查看周围布局的所有子元素,并为其中的所有ImageView对象设置颜色。分隔符被实现为ImageView使用可绘制对象,因此无法仅更改颜色。注意:使用的替代方法setColorFilter()将在这里用适当颜色的可绘制对象替换 ImageView 中的可绘制对象。

感谢您的挑战,弄清楚这一点很有趣:-D

于 2013-02-08T10:41:37.403 回答
2

顺便说一句,它的答案很晚,也许它对某人有用。创建自定义警报对话框并具有与默认警报对话框相同的简洁按钮。按照下面的简单方法

final AlertDialog.Builder demoDialog = new AlertDialog.Builder(this);
        final LayoutInflater inflator = this.getLayoutInflater();
        final View view = inflator.inflate(R.layout.passcode_req_dialog_template, null);

        demoDialog.setView(view)

            .setPositiveButton(R.string.ok_button_text, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            })

            .setNegativeButton(R.string.cancel_button_text, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            });

        final AlertDialog dialog = passwordDialog.create();
        dialog.show();
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                //Get the work done here when pressing positive button
                dialog.dismiss(); 
            }
        });

        dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                //Get the work done here when pressing negative button
                dialog.dismiss();   
            }
        });
于 2013-12-16T12:11:28.900 回答
1

尝试创建一个custom layoutfor 对话框并将其提供layout给您的警报对话框,方法是使用

dialog.setContentView(R.layout.customDialogLayout);

您可以查看自定义对话框的此示例

于 2013-02-08T10:44:17.183 回答
0

你可以使用这个项目AlertDialogPro。将此项目包含到您的项目中并定义您的主题,如下所示:

<style name="YourAppTheme.AlertDialogProTheme" parent="AlertDialogProTheme.Holo.Light">
    <!-- Custom the title -->
    <item name="android:windowTitleStyle">@style/YourDialogWindowTitle</item>
    <!-- Change the title line to orange -->
    <item name="adpTitleDividerBackground">#E5492A</item>
</style>

<style name="YourDialogWindowTitle" parent="DialogWindowTitle.Holo.Light">
    <item name="android:textColor">#E5492A</item>
</style>

并使用属性“alertDialogProTheme”将此主题指定为您的应用程序主题:

<style name="AppTheme" parent="AppBaseTheme">
  ...
  <item name="alertDialogProTheme">@style/YourAppTheme.AlertDialogProTheme</item>
</style>

使用 AlertDialogPro.Builder 构建对话框:

AlertDialogPro.Builder builder = new AlertDialogPro.Builder(getContext());
builder.setTitle(R.string.app_name).
    setMessage("Message").
    setPositiveButton("Rate Now", null).
    setNeutralButton("Remind me later", null).
    setNegativeButton("No,thanks", null).
    show();

截屏

于 2014-10-06T03:09:26.427 回答