Android AlertDialogs中的按钮样式

Android AlertDialogs中的按钮样式,android,android-alertdialog,Android,Android Alertdialog,有人知道如何覆盖AlertDialog按钮的默认样式吗?我已经在Android源代码中查找和尝试了不同的东西,但我还没有找到一种可行的方法 下面的内容可以用来改变背景,但对按钮没有任何作用myTheme通过清单应用于整个。(为了清晰起见,删除了一些其他项目,但它们仅与标题栏相关。) @样式/自定义按钮样式 @风格/主题 @可绘制/对话框\u加载\u背景 @可绘制/对话框\u警报\u顶部 @可绘图/对话框报警中心 @可绘制/对话框\u警报\u底部 @样式/自定义按钮样式 有什么想法吗?请参阅下

有人知道如何覆盖AlertDialog按钮的默认样式吗?我已经在Android源代码中查找和尝试了不同的东西,但我还没有找到一种可行的方法

下面的内容可以用来改变背景,但对按钮没有任何作用
myTheme
通过清单应用于整个
。(为了清晰起见,删除了一些其他项目,但它们仅与标题栏相关。)


@样式/自定义按钮样式
@风格/主题
@可绘制/对话框\u加载\u背景
@可绘制/对话框\u警报\u顶部
@可绘图/对话框报警中心
@可绘制/对话框\u警报\u底部
@样式/自定义按钮样式

有什么想法吗?

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

不正确:


我想你必须实现你自己的
对话框
类。

鉴于Snowflake先生的推理是不准确的,我冒昧地提供另一个答案

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

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

在问题的标记中,父项=“@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”等提供(背景)绘图功能

自定义警报对话框主题将打开一个方法,以提供属性,如windowBackground、windowTitleStyle等,但如前所述,您需要一个Android版本,该版本支持警报对话框主题的属性/项。我不知道这是什么时候推出的,但它不是安卓2.2,Eclipse会告诉你

我没有足够的资源来验证Snowflake先生的结论,即不可能用XML来设计警报对话框按钮,但除非我们面对Android的一个令人讨厌的方面,其中一个功能确实缺失,否则我觉得不太可能

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

<style name="customButtonStyle" />

因此,从我的观点来看,警报对话框按钮不符合Widget.Button的结论还没有得到证实

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

您可以覆盖“buttonBarButtonStyle”而不是“buttonStyle”,如下所示:

<style name="dialogAlertTheme" parent="@android:style/Theme.Dialog.Alert">
  <item name="android:buttonBarButtonStyle">@style/customButtonStyle</item>
</style>

@样式/自定义按钮样式

我制作了这样一种方法,可以更改默认按钮的颜色和背景

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);
    }
}
这可能对某些人有用

试试这个:

 <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>
@style/Widget.AppCompat.ButtonBar
@style/AppTheme.Button
@风格/你的我
@风格/你的我
@风格/你的我

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

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

@颜色/原色
@颜色/原色暗
@颜色/颜色重音
@样式/AlertDialogTheme.Light
@样式/插入自定义按钮样式此处

这将保留主题的颜色,但会替换按钮的样式,例如匹配
小部件.MaterialComponents.Button.TextButton

这允许我自定义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();
        }
    });
    ...
}

嗯,那太烦人了;考虑到将按钮样式应用于“正常”活动按钮很容易,更改对话框按钮不应该是一件不寻常的事情。在正常活动中,使用xml定义内容视图的布局。对话框为您执行此操作,因此您无权访问布局xml。实现您自己的对话框(可能仅通过一个setContentView()调用)允许您使用不同的xml,从而为按钮使用不同的样式。如何将AlertDialog子类化,以便将AlertDialog.Builder与子类一起使用?这是在Java等OO语言中唯一正确的答案,这确实不是做事情的首选方式,特别是考虑到可维护性。需要API 11或higher@TimCastelijns我觉得这离题了。高质量的回答应该提供这一信息。事实上,在某些情况下,人们必须维护向后兼容的应用程序。当我添加parent=“@android:style/AlertDialog”时,会出现构建错误到dialogAlertTheme:
resource android:style/Theme.Dialog.Alert是私有的。
按照@Benoit的建议将父级更改为
ThemeOverlay.AppCompat.Dialog.Alert
,这似乎是可行的。如果您解释这些行应该放在哪里,这将更有用。我确实想不出来…谢谢你,我找了好几个小时了@RenniePet你应该把它放在你的对话主题中,这个主题可能应该扩展
ThemeOverlay.AppCompat.Dialog.Alert
,并且你在主题中使用@style/yourldialogtheme声明只有在我从“android:alertDialogTheme”中删除了“android:”部分后才起作用。谢谢。@Joh
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();
        }
    });
    ...
}