Как я могу изменить цвет текста кнопки диалога по умолчанию в Android 5

160

В моем приложении много диалоговых окон с предупреждениями. Это макет по умолчанию, но я добавляю положительные и отрицательные кнопки в диалог. Таким образом, кнопки получают цвет текста по умолчанию Android 5 (зеленый). Я пытался изменить это безуспешно. Есть идеи, как изменить цвет текста?

Мой Пользовательский диалог:

public class MyCustomDialog extends AlertDialog.Builder {

    public MyCustomDialog(Context context,String title,String message) {
        super(context);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
        View viewDialog = inflater.inflate(R.layout.dialog_simple, null, false);

        TextView titleTextView = (TextView)viewDialog.findViewById(R.id.title);
        titleTextView.setText(title);
        TextView messageTextView = (TextView)viewDialog.findViewById(R.id.message);
        messageTextView.setText(message);

        this.setCancelable(false);

        this.setView(viewDialog);

    } }

Создание диалога:

MyCustomDialog builder = new MyCustomDialog(getActivity(), "Try Again", errorMessage);
builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            ...
                        }
}).show();

Эта негативная кнопка является диалоговой кнопкой по умолчанию и принимает зеленый цвет по умолчанию от Android 5 Lollipop.

Большое спасибо

Пользовательский диалог с зеленой кнопкой

FOMDeveloper
источник
Почти повторяющийся вопрос / ответ stackoverflow.com/a/29810469/2291, который я считаю более применимым в наши дни.
Джон Адамс

Ответы:

191

Вы можете AlertDialogсначала попытаться создать объект, а затем использовать его, чтобы настроить изменение цвета кнопки, а затем показать его. (Обратите внимание , что на builderобъект вместо вызова show()мы называем , create()чтобы получить AlertDialogобъект:

//1. create a dialog object 'dialog'
MyCustomDialog builder = new MyCustomDialog(getActivity(), "Try Again", errorMessage); 
AlertDialog dialog = builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    ...
                }

            }).create();

//2. now setup to change color of the button
dialog.setOnShowListener( new OnShowListener() {
    @Override
    public void onShow(DialogInterface arg0) {
        dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(COLOR_I_WANT);
    }
});

dialog.show()

Причина, по которой вы должны сделать это onShow()и не можете просто получить эту кнопку после создания диалогового окна, заключается в том, что кнопка еще не была создана.

Я изменился, AlertDialog.BUTTON_POSITIVEчтобы AlertDialog.BUTTON_NEGATIVEотразить изменение в вашем вопросе. Хотя странно, что кнопка «ОК» будет отрицательной кнопкой. Обычно это положительная кнопка.

trungdinhtrong
источник
Спасибо за ответ, но у меня нет этого метода в AlertDialog. Смотрите мой обновленный пост.
FOMDeveloper
5
Этот метод находится в классе AlertDialog, а не в классе Builder. Поэтому вместо вызова Builder.show () вы можете использовать Builder.create (), который возвращает класс AlertDialog. Затем вы настраиваете слушателя, а затем вызываете show () для объекта
AlertDialog
3
Но должен быть другой способ сделать это. Похоже, это цвет из темы, мы можем изменить его через тему / стиль?
milosmns
Это потрясающе. Только что попробовал в Xamarin.Android и он отлично работает. Большое спасибо.
Perozzo
282

Вот естественный способ сделать это со стилями:

Если ваш AppThemeнаследуется от Theme.MaterialComponents, то:

<style name="AlertDialogTheme" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
    <item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
    <item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
</style>

<style name="NegativeButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
    <item name="android:textColor">#f00</item>
</style>

<style name="PositiveButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
    <item name="android:textColor">#00f</item>
</style>

Если ваш AppThemeнаследуется от Theme.AppCompat:

<style name="AlertDialogTheme" parent="ThemeOverlay.AppCompat.Dialog.Alert">
    <item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
    <item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
</style>

<style name="NegativeButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
    <item name="android:textColor">#f00</item>
</style>

<style name="PositiveButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
    <item name="android:textColor">#00f</item>
</style>

Используйте свой AlertDialogThemeв своемAppTheme

<item name="alertDialogTheme">@style/AlertDialogTheme</item>

или в конструкторе

androidx.appcompat.app.AlertDialog.Builder(context, R.style.AlertDialogTheme)
Александр Перфильев
источник
34
Мне пришлось изменить buttonBarNegativeButtonStyle на android: buttonBarNegativeButtonStyle и buttonBarPositiveButtonStyle на android: buttonBarPositiveButtonStyle. Тогда это сработало (API 21+).
Влад
23
Не забудьте использовать android.support.v7.app.AlertDialog вместо android.app.AlertDialog. Чушь ошибка заняла у меня 2 часа
thanhbinh84
2
Мне пришлось изменить в родительском AlertDialogTheme на «Base.Theme.AppCompat.Light.Dialog.Alert». И удалите buttonBarNegativeButtonStyle & buttonBarPositiveButtonStyle. Также добавьте в <item name = "colorAccent"> @ color / dashboard_red_color </ item> в AlertDialogTheme. работает отлично.
зефир
3
Это не работает при использовании новой библиотеки материалов, com.google.android.material:material:1.0.0-beta01и я использую Theme.MaterialComponents.Light.Dialog.Alert
Sanjeev
2
@LX обновил ответ, включив тему компонентов материала
Александр Перфильев
120

Цвет кнопок и другой текст также можно изменить с помощью темы:

Значения-21 / styles.xml

<style name="AppTheme" parent="...">
  ...
  <item name="android:timePickerDialogTheme">@style/AlertDialogCustom</item>
  <item name="android:datePickerDialogTheme">@style/AlertDialogCustom</item>
  <item name="android:alertDialogTheme">@style/AlertDialogCustom</item>
</style>

<style name="AlertDialogCustom" parent="android:Theme.Material.Light.Dialog.Alert">
  <item name="android:colorPrimary">#00397F</item>
  <item name="android:colorAccent">#0AAEEF</item>
</style>

Результат:

диалог Выбор даты

peceps
источник
1
В настоящее время я не знаю, как изменить цвет флажка или только цвет кнопки. Цвет акцента меняет их обоих.
peceps
4
Мне понравился этот подход, но я чувствую, что ответ на stackoverflow.com/a/29810469/2291 - немного более чистый способ сделать это.
Джон Адамс
12
Чтобы это работало в моем проекте, мне пришлось удалить android:деталь из android:alertDialogThemeи из android:colorAccent.
запрет геоинженерии
2
Наличие префикса android: для значений зависит от того, куда вы помещаете styles.xml, в values ​​или values-vXX
peceps
1
Чтобы это работало с AppCompat и простой папкой значений, просто следуйте изменениям, предложенным @ ban-geoengineering
Феликс
94

Самое простое решение:

dialog.show(); //Only after .show() was called
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(neededColor);
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(neededColor);
Артемий
источник
4
Эти поля не должны ссылаться из нестатической переменной, должны быть AlertDialog.BUTTON_NEGATIVEи т. Д.
Джо Махер
Это был лучший и самый простой способ сделать это. Обратите внимание, что я не использовал «создать», а взял диалоговое окно после show (). Например, AlertDialog dialog = builder.show ();
Стивен Маккормик
2
Хотя это решение может работать, логически оно имеет недостатки. Что происходит здесь, вы сначала показываете диалоговое окно, а затем изменяете его внешний вид. В зависимости от базовой реализации (которая может изменяться со временем) и производительности устройства, теоретически вы можете увидеть «мерцание», когда пользователь видит диалоговое окно, а затем быстро меняет его внешний вид.
trungdinhtrong
31

Есть два способа изменить цвет кнопки диалога.

Основной способ

Если вы просто хотите изменить деятельность, напишите две строки ниже alertDialog.show();

alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.colorPrimary));
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.colorPrimaryDark));

рекомендуемые

Я рекомендую добавить тему для AlertDialogin, styles.xmlчтобы вам не приходилось писать один и тот же код снова и снова при каждом вызове действия / диалога. Вы можете просто создать стиль и применить эту тему в диалоговом окне. Поэтому, когда вы захотите изменить цвет окна AlertDialog, просто измените цвет в файле styles.xml, и все диалоговые окна будут обновлены во всем приложении.

<style name="AlertDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="colorAccent">@color/colorPrimary</item>
</style>

И применить тему в AlertDialog.Builder

AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AlertDialogTheme);
Хасснайн Джамиль
источник
Этот ответ является наиболее чистым, но при этом остается верным.
Big_Chair
11

Если вы хотите изменить цвет текста кнопок (положительный, отрицательный, нейтральный), просто добавьте свой собственный стиль диалога:

<item name="colorAccent">@color/accent_color</item>

Итак, ваш стиль диалога должен выглядеть так:

<style name="AlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="android:textColor">@android:color/black</item>
    <item name="colorAccent">@color/topeka_accent</item>
</style>
Станислав Захаров
источник
6
<style name="AlertDialogCustom" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="android:colorPrimary">#00397F</item>
    <item name="android:textColorPrimary">#22397F</item>
    <item name="android:colorAccent">#00397F</item>
    <item name="colorPrimaryDark">#22397F</item>
</style>

Цвет кнопок и другого текста также можно изменить с помощью appcompat:

Arade
источник
Theme.AppCompat.Light.Dialog.Alert прекрасно работает, чтобы изменить цвет кнопки на белый.
Лео К,
6
  1. В теме / стиле вашего приложения добавьте следующие строки:

    <item name="android:buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
    <item name="android:buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
    <item name="android:buttonBarNeutralButtonStyle">@style/NeutralButtonStyle</item>
  2. Затем добавьте следующие стили:

    <style name="NegativeButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
        <item name="android:textColor">@color/red</item>
    </style>
    
    <style name="PositiveButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
        <item name="android:textColor">@color/red</item>
    </style>
    
    <style name="NeutralButtonStyle" 
    parent="Widget.MaterialComponents.Button.TextButton.Dialog">
        <item name="android:textColor">#00f</item>
    </style>

Использование этого метода избавляет от необходимости устанавливать тему в конструкторе AlertDialog.

Джо Мюллер
источник
4

Просто как примечание:

Цвет кнопок (и весь стиль) также зависит от текущей темы, которая может быть довольно разной, если вы используете

android.app.AlertDialog.Builder builder = new AlertDialog.Builder()

или

android.support.v7.app.AlertDialog.Builder builder = new AlertDialog.Builder()

(Лучше использовать второй)

Тобиас
источник
3

Вот как вы это делаете: Простой способ

// Initializing a new alert dialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.message);
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        doAction();
    }
});
builder.setNegativeButton(R.string.cancel, null);

// Create the alert dialog and change Buttons colour
AlertDialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface arg0) {
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.red));
        dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.blue));
        //dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(getResources().getColor(R.color.black));
    }
});
dialog.show();
MrGuy
источник
1

для меня это было иначе, я использовал тему кнопки

<style name="ButtonLight_pink" parent="android:Widget.Button">
      <item name="android:background">@drawable/light_pink_btn_default_holo_light</item>
      <item name="android:minHeight">48dip</item>
      <item name="android:minWidth">64dip</item>
      <item name="android:textColor">@color/tab_background_light_pink</item>
    </style>

и потому что

андроид: TextColor

там был белый цвет… я не видел никакого текста кнопки (кнопки диалога в основном тоже кнопки). там мы идем, изменили это, исправили это.

CV2
источник