¿Cómo puedo cambiar el color del texto del botón de diálogo predeterminado en Android 5?

160

Tengo muchos cuadros de diálogo de alerta en mi aplicación. Es un diseño predeterminado, pero estoy agregando botones positivos y negativos al cuadro de diálogo. Entonces, los botones obtienen el color de texto predeterminado de Android 5 (verde). Traté de cambiarlo sin éxito. ¿Alguna idea de cómo cambiar ese color de texto?

Mi cuadro de diálogo personalizado:

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

    } }

Crear el 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();

Ese Boton negativo es un botón de diálogo predeterminado y toma el color verde predeterminado de Android 5 Lollipop.

Muchas gracias

Diálogo personalizado con botón verde

FOMDeveloper
fuente
Casi duplica la pregunta / respuesta stackoverflow.com/a/29810469/2291 que creo que es más aplicable en estos días.
Jon Adams

Respuestas:

191

Puede intentar crear AlertDialogprimero el objeto y luego usarlo para configurarlo para cambiar el color del botón y luego mostrarlo. (Tenga en cuenta que en el builderobjeto en lugar de llamar show(), llamamos create()para obtener el 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()

La razón por la que debe hacerlo onShow()y no puede obtener ese botón después de crear su cuadro de diálogo es que el botón aún no se habría creado.

Cambié AlertDialog.BUTTON_POSITIVEa AlertDialog.BUTTON_NEGATIVEpara reflejar el cambio en tu pregunta. Aunque es extraño que el botón "Aceptar" sea un botón negativo. Por lo general, es el botón positivo.

trungdinhtrong
fuente
Gracias por su respuesta, pero no tengo ese método en AlertDialog. Ver mi publicación actualizada.
FOMDeveloper
55
Ese método está en la clase AlertDialog, no en la clase Builder. Entonces, en lugar de llamar a Builder.show (), puede Builder.create (), que devuelve la clase AlertDialog. Luego configura el oyente y luego llama a show () en el objeto
AlertDialog
3
Pero debe haber otra forma de hacer esto. Parece que es un color del tema, ¿podemos cambiarlo a través del tema / estilo?
milosmns
Esto es perfecto. Acabo de probar en Xamarin.Android y funciona perfectamente. Muchas gracias.
perozzo
282

Aquí hay una forma natural de hacerlo con estilos:

Si AppThemese hereda de Theme.MaterialComponents, entonces:

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

Si AppThemese hereda 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>

Usa tu AlertDialogThemeen tuAppTheme

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

o en constructor

androidx.appcompat.app.AlertDialog.Builder(context, R.style.AlertDialogTheme)
Alexander Perfilyev
fuente
34
Tuve que cambiar buttonBarNegativeButtonStyle a android: buttonBarNegativeButtonStyle y buttonBarPositiveButtonStyle a android: buttonBarPositiveButtonStyle. Luego funcionó (API 21+).
Vlad
23
Recuerde usar android.support.v7.app.AlertDialog en lugar de android.app.AlertDialog. El error de mierda me llevó 2 horas
thanhbinh84
2
Tuve que cambiar en AlertDialogTheme's parent a "Base.Theme.AppCompat.Light.Dialog.Alert". Y elimine buttonBarNegativeButtonStyle & buttonBarPositiveButtonStyle. Agregue también <item name = "colorAccent"> @ color / dashboard_red_color </item> en AlertDialogTheme. Y funciona perfectamente.
zephyr
3
Esto no funciona cuando uso una nueva biblioteca de materiales com.google.android.material:material:1.0.0-beta01y estoy usando Theme.MaterialComponents.Light.Dialog.Alert
Sanjeev
2
Respuesta actualizada de @LX para incluir el tema de componentes de material
Alexander Perfilyev
120

El color de los botones y otro texto también se puede cambiar a través del 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>

El resultado:

Diálogo Selector de fechas

peceps
fuente
1
Actualmente no conozco una manera de cambiar el color de la casilla de verificación o solo el color del botón. El color de acento los cambia a ambos.
Peceps
44
Me gustó este enfoque, pero creo que la respuesta en stackoverflow.com/a/29810469/2291 es una forma un poco más limpia de hacerlo.
Jon Adams
12
Para que esto funcione en mi proyecto, tuve que quitar la android:parte desde android:alertDialogThemey hacia android:colorAccent.
prohibición de geoingeniería
2
Tener el prefijo android: en los valores depende de dónde coloque styles.xml, en valores o en valores-vXX
aceptado el
1
Para hacer que esto funcione con AppCompat y una carpeta de valores simple, simplemente siga los cambios sugeridos por @ ban-geoengineering
Felix
94

La solución más simple es:

dialog.show(); //Only after .show() was called
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(neededColor);
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(neededColor);
Artemiy
fuente
44
Esos campos no deben ser referenciados desde la variable no estática, deben ser AlertDialog.BUTTON_NEGATIVEetc.
Joe Maher
Esta fue la mejor y más simple forma de hacer esto. Tenga en cuenta que no utilicé "crear" sino que agarré el cuadro de diálogo después del show (). Al igual que AlertDialog dialog = builder.show ();
Stephen McCormick
2
Si bien esta solución podría funcionar, lógicamente es defectuosa. Lo que sucede aquí es que primero muestra el diálogo y luego cambia su apariencia. Depende de la implementación subyacente (que podría modificarse con el tiempo) y el rendimiento del dispositivo, teóricamente podría ver un "parpadeo" donde el usuario ve aparecer un diálogo y luego cambiar rápidamente su apariencia.
trungdinhtrong
31

Hay dos formas de cambiar el color del botón de diálogo.

Forma básica

Si solo desea cambiar una actividad, escriba las dos líneas siguientes después de 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

Recomendaré agregar un tema para AlertDialogadentro styles.xmlpara que no tenga que escribir el mismo código una y otra vez en cada llamada de actividad / diálogo. Simplemente puede crear un estilo y aplicar ese tema en el cuadro de diálogo. Entonces, cuando desee cambiar el color del cuadro de diálogo AlertDialog, simplemente cambie el color en styles.xml y todos los cuadros de diálogo se actualizarán en toda la aplicación.

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

Y aplica el tema en AlertDialog.Builder

AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AlertDialogTheme);
Hassnain Jamil
fuente
Esta respuesta es la más limpia y sigue siendo correcta.
Big_Chair
11

Si desea cambiar el color del texto de los botones (positivo, negativo, neutro) simplemente agregue a su estilo de diálogo personalizado:

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

Entonces, su estilo de diálogo debe verse así:

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

El color de los botones y otro texto también se puede cambiar usando appcompat:

Arade
fuente
Theme.AppCompat.Light.Dialog.Alert funciona muy bien para cambiar el color del botón a blanco.
Leo K
6
  1. En el tema / estilo de su aplicación, agregue las siguientes líneas:

    <item name="android:buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
    <item name="android:buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
    <item name="android:buttonBarNeutralButtonStyle">@style/NeutralButtonStyle</item>
  2. Luego agregue los siguientes 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>

El uso de este método hace innecesario configurar el tema en el generador AlertDialog.

Joe Muller
fuente
4

Solo como una nota al margen:

Los colores de los botones (y todo el estilo) también dependen del tema actual, que puede ser bastante diferente cuando usas

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

o

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

(Mejor usar el segundo)

Tobias
fuente
3

Así es como lo haces: manera simple

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

para mí fue diferente, usé un tema de botón

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

y porqué

android: textColor

estaba blanco allí ... no vi ningún texto de botón (los botones de diálogo son básicamente botones también). ahí vamos, lo cambiamos, lo arreglamos.

cV2
fuente