Como posso alterar a cor do texto do botão de diálogo padrão no android 5

160

Eu tenho muitas caixas de diálogo de alerta no meu aplicativo. É um layout padrão, mas estou adicionando botões positivos e negativos à caixa de diálogo. Portanto, os botões obtêm a cor do texto padrão do Android 5 (verde). Eu tentei mudar isso sem sucesso. Alguma idéia de como alterar a cor do texto?

Minha caixa de diálogo personalizada:

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

    } }

Criando a caixa de diálogo:

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

Esse negativeButton é um botão de diálogo padrão e usa a cor verde padrão do Android 5 Lollipop.

Muito Obrigado

Caixa de diálogo personalizada com botão verde

FOMDeveloper
fonte
Pergunta / resposta quase duplicada stackoverflow.com/a/29810469/2291 que considero mais aplicável atualmente.
John Adams

Respostas:

191

Você pode tentar criar o AlertDialogobjeto primeiro e depois usá-lo para configurar a alteração da cor do botão e exibi-lo. (Observe que no builderobjeto, em vez de chamar show(), chamamos create()para obter o AlertDialogobjeto:

//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()

O motivo pelo qual você precisa ativá-lo onShow()e não pode simplesmente acessar esse botão após criar sua caixa de diálogo é que o botão ainda não havia sido criado.

Mudei AlertDialog.BUTTON_POSITIVEpara AlertDialog.BUTTON_NEGATIVErefletir a alteração na sua pergunta. Embora seja estranho que o botão "OK" seja um botão negativo. Geralmente é o botão positivo.

trungdinhtrong
fonte
Obrigado pela resposta, mas eu não tenho esse método no AlertDialog. Veja minha postagem atualizada.
usar o seguinte comando
5
Esse método está na classe AlertDialog, não na classe Builder. Portanto, em vez de chamar Builder.show (), você pode Builder.create (), que retorna a classe AlertDialog. Você, então, configurar o show chamada ouvinte e, em seguida, () no objeto AlertDialog
trungdinhtrong
3
Mas deve haver outra maneira de fazer isso. Parece que é uma cor do tema, podemos alterá-lo através do tema / estilo?
milosmns
Isto é perfeito. Apenas tentei no Xamarin.Android e funciona perfeitamente. Muito obrigado.
Perozzo 31/08/19
282

Aqui está uma maneira natural de fazer isso com estilos:

Se você AppThemeé herdado de Theme.MaterialComponents, então:

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

Se você AppThemeé herdado de 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>

Use o seu AlertDialogThemeno seuAppTheme

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

ou no construtor

androidx.appcompat.app.AlertDialog.Builder(context, R.style.AlertDialogTheme)
Alexander Perfilyev
fonte
34
Eu tive que mudar buttonBarNegativeButtonStyle para android: buttonBarNegativeButtonStyle e buttonBarPositiveButtonStyle para android: buttonBarPositiveButtonStyle. Então funcionou (API 21+).
Vlad
23
Lembre-se de usar android.support.v7.app.AlertDialog em vez de android.app.AlertDialog. Bullshit erro me levou 2 horas
thanhbinh84
2
Eu tive que mudar o pai do AlertDialogTheme para "Base.Theme.AppCompat.Light.Dialog.Alert". E remova buttonBarNegativeButtonStyle e buttonBarPositiveButtonStyle. Adicione também <item name = "colorAccent"> @ color / dashboard_red_color </item> em AlertDialogTheme. nd funciona perfeitamente.
Zephyr
3
Isso não funciona ao usar a nova biblioteca de materiais com.google.android.material:material:1.0.0-beta01e eu estou usando Theme.MaterialComponents.Light.Dialog.Alert
Sanjeev
2
@LX resposta atualizado para incluir material de componentes tema
Alexander Perfilyev
120

A cor dos botões e outros textos também pode ser alterada via tema:

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

O resultado:

Diálogo Selecionador de data

peceps
fonte
1
Atualmente, não conheço uma maneira de alterar apenas a cor da caixa de seleção ou do botão. A cor de destaque altera os dois.
peceps 10/09/2015
4
Gostei dessa abordagem, mas acho que a resposta em stackoverflow.com/a/29810469/2291 é uma maneira um pouco mais limpa de fazer isso.
John Adams
12
Para que isso funcionasse no meu projeto, tive que remover a android:peça de android:alertDialogThemee para android:colorAccent.
ban-geoengenharia
2
Ter o android: prefixo nos valores depende de onde você coloca styles.xml, em valores ou valores-vxx
peceps
1
Para fazer este trabalho com AppCompat e uma pasta de valores simples, basta seguir as mudanças sugeridas por @ ban-geoengenharia
Felix
94

A solução mais simples é:

dialog.show(); //Only after .show() was called
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(neededColor);
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(neededColor);
Artemiy
fonte
4
Esses campos não devem ser referenciados a partir da variável não estática, devem ser AlertDialog.BUTTON_NEGATIVEetc.
Joe Maher
Essa foi a melhor e mais simples maneira de fazer isso. Observe que eu não usei o "create" e peguei a caixa de diálogo após o show (). Como a caixa de diálogo AlertDialog = builder.show ();
Stephen McCormick
2
Embora essa solução possa funcionar, logicamente é falha. O que acontece aqui é que você primeiro mostra a caixa de diálogo e depois muda sua aparência. Depende da implementação subjacente (que pode ser alterada ao longo do tempo) e do desempenho do dispositivo, você poderia teoricamente ver um "flicker" em que o usuário vê uma caixa de diálogo aparecer e depois alterar rapidamente sua aparência.
trungdinhtrong
31

Existem duas maneiras de alterar a cor do botão da caixa de diálogo.

Maneira básica

Se você quiser apenas alterar uma atividade, escreva as duas linhas abaixo após alertDialog.show();

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

Recomendado

Recomendamos adicionar um tema para AlertDialogin styles.xmlpara que você não precise escrever o mesmo código repetidamente em cada atividade / chamada de diálogo. Você pode apenas criar um estilo e aplicar esse tema na caixa de diálogo. Portanto, sempre que você desejar alterar a cor da caixa AlertDialog, basta alterar a cor em styles.xml e todas as caixas de diálogo serão atualizadas em todo o aplicativo.

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

E aplique o tema em AlertDialog.Builder

AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AlertDialogTheme);
Hassnain Jamil
fonte
Esta resposta é a mais limpa enquanto ainda está correta.
Big_Chair 6/01
11

Se você deseja alterar a cor do texto dos botões (positivo, negativo, neutro), basta adicionar ao seu estilo de diálogo personalizado:

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

Portanto, seu estilo de diálogo deve ficar assim:

<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>
Stanislav Zakharov
fonte
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>

A cor dos botões e outros textos também pode ser alterada usando appcompat:

Arade
fonte
O Theme.AppCompat.Light.Dialog.Alert funciona muito bem para alterar a cor do botão para branco.
Leo K
6
  1. No tema / estilo do seu aplicativo, adicione as seguintes linhas:

    <item name="android:buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
    <item name="android:buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
    <item name="android:buttonBarNeutralButtonStyle">@style/NeutralButtonStyle</item>
  2. Em seguida, adicione os seguintes estilos:

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

O uso desse método torna desnecessário definir o tema no construtor AlertDialog.

Joe Muller
fonte
4

Apenas como uma observação lateral:

As cores dos botões (e todo o estilo) também dependem do tema atual, que pode ser bastante diferente quando você usa

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

ou

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

(Melhor usar o segundo)

Tobias
fonte
3

Aqui está como você faz: Maneira simples

// 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
fonte
1

para mim foi diferente, eu usei um tema de botão

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

e porque

android: textColor

estava branco lá… não vi nenhum texto do botão (os botões da caixa de diálogo também são basicamente botões). lá vamos nós, mudou, corrigiu.

cV2
fonte