29

有谁知道如何覆盖 AlertDialog 按钮的默认样式?我已经查看了主题样式的 Android 源代码,并尝试了不同的东西,但我一直无法找到一种可行的方法。

我下面的内容可用于更改背景,但对按钮没​​有任何作用。通过清单myTheme应用于整体。<application>(为清楚起见,删除了其他一些项目,但它们仅与标题栏有关。)

<style name="myTheme" parent="android:Theme">
    <item name="android:buttonStyle">@style/customButtonStyle</item>
    <item name="android:alertDialogStyle">@style/dialogAlertTheme</item>
</style>

<style name="dialogAlertTheme" parent="@android:style/Theme.Dialog.Alert">
    <item name="android:fullDark">@drawable/dialog_loading_background</item>
    <item name="android:topDark">@drawable/dialog_alert_top</item>
    <item name="android:centerDark">@drawable/dialog_alert_center</item>
    <item name="android:bottomDark">@drawable/dialog_alert_bottom</item>
    <!-- this last line makes no difference to the buttons -->
    <item name="android:buttonStyle">@style/customButtonStyle</item> 
</style>

有任何想法吗?

4

7 回答 7

30

鉴于 MrSnowflake 的推理不准确,我冒昧地提供另一个答案。

Steve Haley 的问题中的标记有问题,它混淆了alertDialogStyle和 alertDialogTheme,很可能是因为在 alertDialogStyle 出现很久之后才引入了 alertDialogTheme。

因此,即使 @android:style/Theme.Dialog.Alert 在您的 Andoid 平台上可用,您仍然无法通过将自定义版本挂钩回您自己的主题来利用其表达能力,除非您的 Android 平台支持android:alertDialogTheme属性/主题项目。(我不确定是否存在这种不一致的 Android 版本,但问题中使用的标记表明确实存在。)

在问题的标记中, parent="@android:style/Theme.Dialog.Alert"除了创建您正在自定义警报对话框主题的错觉之外什么都不做,而实际上您只是在自定义警报对话框样式。

这就是标记的样子;并非所有 Android 版本都支持所有功能。

<style name="myTheme" parent="android:Theme">
    <item name="android:buttonStyle">@style/customButtonStyle</item>
    <item name="android:alertDialogStyle">@style/dialogAlertStyle</item>
    <item name="android:alertDialogTheme">@style/dialogAlertTheme</item>
</style>

<style name="dialogAlertStyle" parent="@android:style/AlertDialog">
    <item name="android:fullDark">[...]</item>
    [...]
</style>

<style name="dialogAlertTheme" parent="@android:style/Theme.Dialog.Alert">
    <item name="android:windowBackground">[...]</item>
    [...]
</style>

自定义警报对话框样式已经存在了很长一段时间,但仅限于为“fullDark”、“topDark”等提供(背景)drawables。

自定义警报对话框主题会打开一个方法来提供诸如 windowBackground、windowTitleStyle 等属性,但如前所述,您需要一个支持主题的 alertDialogThem 属性/项目的 Android 版本。我不知道它是什么时候引入的,但它不是 Android 2.2,而且 Eclipse 无论如何都会告诉你......

我没有资源来验证 MrSnowflake 的结论,即不可能在 XML 中设置警报对话框按钮的样式,但除非我们面临 Android 中确实缺少某项功能的某些令人讨厌的方面,否则我认为这不太可能。

事实上,问题中缺少的是这方面最相关的部分,即

<style name="customButtonStyle" />

因此,从我的角度来看,警报对话框按钮不服从 Widget.Button 的结论尚未得到证实。

综合结论:独立于其他小部件设置警报对话框样式的能力在 Android 中是有限的,但随着新版本在这方面的改进,它变得更加强大。

于 2012-12-07T11:39:14.377 回答
11

试试这个:

 <item name="buttonBarStyle">@style/Widget.AppCompat.ButtonBar</item>
    <item name="buttonBarButtonStyle">@style/AppTheme.Button</item>
    <item name="buttonBarPositiveButtonStyle">@style/YoursTheme</item>
    <item name="buttonBarNegativeButtonStyle">@style/YoursTheme</item>
    <item name="buttonBarNeutralButtonStyle">@style/YoursTheme</item>
于 2016-07-26T14:04:17.317 回答
6

您可以像这样覆盖“buttonBarButtonStyle”而不是“buttonStyle”:

<style name="dialogAlertTheme" parent="@android:style/Theme.Dialog.Alert">
  <item name="android:buttonBarButtonStyle">@style/customButtonStyle</item>
</style>
于 2014-07-24T10:09:40.060 回答
4

如果您使用的是材质组件:

<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:alertDialogTheme">@style/AlertDialogTheme.Light</item>
</style>

<style name="AlertDialogTheme.Light" parent="ThemeOverlay.MaterialComponents.Dialog.Alert" >
    <item name="android:buttonBarButtonStyle">@style/InsertCustomButtonStyleHere</item>
</style>

这将保留主题的颜色,但会替换按钮的样式,例如 match Widget.MaterialComponents.Button.TextButton

于 2018-12-11T20:32:56.123 回答
2

我做了一个这样的方法,它将改变默认按钮颜色和背景

public static void setDefaultColorTextForDialogButton(AlertDialog alertDialog, Resources r) {
    Button b;

    b= alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
    if(b != null) {
        b.setTextColor(r.getColor(R.color.default_text));
        b.setBackgroundColor(Color.WHITE);
    }
    b = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
    if(b != null) {
        b.setTextColor(r.getColor(R.color.default_text));
        b.setBackgroundColor(Color.WHITE);
    }
    b = alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
    if(b != null) {
        b.setTextColor(r.getColor(R.color.default_text));
        b.setBackgroundColor(Color.WHITE);
    }
}

这可能对某些人有用!!!

于 2015-03-24T17:51:17.280 回答
1

请参阅下面的所有其他答案。

不正确:

我想你必须实现你自己的Dialog类。

于 2010-03-26T14:56:36.560 回答
0

这允许我自定义我的 AlertDialog 按钮和布局。

private void openLookupTableEditDialog() {
    AlertDialog.Builder openLookupTableEditDialog = new AlertDialog.Builder(this);
    View v = this.getLayoutInflater().inflate(R.layout.lookup_table_edit_dialog, null);

    openLookupTableEditDialog.setView(v);
    final AlertDialog alert = openLookupTableEditDialog.create();
    openLookupTableEditDialog.setTitle("Lookup Table Edit");
    Button btnSpecies = v.findViewById(R.id.btnSpeciesLookupEdit);
    Button btnLocation = v.findViewById(R.id.btnLocationLookupEdit);
    Button btnSampler = v.findViewById(R.id.btnSamplerLookupEdit);
    Button btnExit = v.findViewById(R.id.btnCloseLookupTableEdit);
    alert.setView(v);
    alert.show();

    btnSpecies.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            editSpeciesTable();
            alert.dismiss();
        }
    });
    btnSampler.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            editSamplerTable();
            alert.dismiss();
        }
    });
    btnLocation.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            editLocationTable();
            alert.dismiss();
        }
    });
    btnExit.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
           alert.dismiss();
        }
    });
    ...
}
于 2021-05-07T15:43:22.037 回答