Jak mogę zmienić domyślny kolor tekstu przycisku okna dialogowego w systemie Android 5


160

W mojej aplikacji jest wiele okien dialogowych z alertami. Jest to układ domyślny, ale do okna dialogowego dodam przyciski pozytywów i negatywów. Tak więc przyciski otrzymują domyślny kolor tekstu Androida 5 (zielony). Próbowałem to zmienić bez powodzenia. Masz pomysł, jak zmienić ten kolor tekstu?

Moje niestandardowe okno dialogowe:

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

    } }

Tworzenie okna dialogowego:

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

Ten NegativeButton jest domyślnym przyciskiem okna dialogowego i przyjmuje domyślny zielony kolor z Androida 5 Lollipop.

Wielkie dzięki

Niestandardowe okno dialogowe z zielonym przyciskiem


Prawie zduplikowane pytanie / odpowiedź stackoverflow.com/a/29810469/2291, które moim zdaniem ma obecnie większe zastosowanie.
Jon Adams

Odpowiedzi:


191

Możesz spróbować AlertDialognajpierw utworzyć obiekt, a następnie użyć go do ustawienia zmiany koloru przycisku, a następnie go pokazać. (Zauważ, że na builderobiekcie zamiast wywoływać show()wywołanie, create()aby pobrać AlertDialogobiekt:

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

Powodem, dla którego musisz to zrobić onShow()i nie możesz po prostu uzyskać tego przycisku po utworzeniu okna dialogowego, jest to, że przycisk nie zostałby jeszcze utworzony.

Zmieniłem się AlertDialog.BUTTON_POSITIVEna, AlertDialog.BUTTON_NEGATIVEaby odzwierciedlić zmianę w Twoim pytaniu. Chociaż to dziwne, że przycisk „OK” byłby przyciskiem ujemnym. Zwykle jest to przycisk pozytywny.


Dziękuję za odpowiedź, ale nie mam tej metody w AlertDialog. Zobacz mój zaktualizowany post.
FOMDeveloper

5
Ta metoda znajduje się w klasie AlertDialog, a nie w klasie Builder. Więc zamiast wywoływać Builder.show () możesz Builder.create (), który zwraca klasę AlertDialog. Następnie konfigurujesz odbiornik, a następnie wywołujesz funkcję show () na obiekcie
AlertDialog

3
Ale musi być inny sposób, aby to zrobić. Wygląda na to, że to kolor z motywu, czy możemy to zmienić za pomocą motywu / stylu?
milosmns

To jest doskonałe. Właśnie wypróbowałem w Xamarin.Android i działa idealnie. Dziękuję Ci bardzo.
perozzo

280

Oto naturalny sposób na zrobienie tego ze stylami:

Jeśli Twój AppThemejest dziedziczony z Theme.MaterialComponents, to:

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

Jeśli Twój AppThemejest dziedziczony z 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>

Użyj swojego AlertDialogThemew swoimAppTheme

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

lub w konstruktorze

androidx.appcompat.app.AlertDialog.Builder(context, R.style.AlertDialogTheme)

34
Musiałem zmienić buttonBarNegativeButtonStyle na android: buttonBarNegativeButtonStyle i buttonBarPositiveButtonStyle na android: buttonBarPositiveButtonStyle. Wtedy zadziałało (API 21+).
Vlad

23
Pamiętaj, aby używać android.support.v7.app.AlertDialog zamiast android.app.AlertDialog. Gówniany błąd zajął mi 2 godziny
thanhbinh84

2
Musiałem zmienić rodzica AlertDialogTheme na „Base.Theme.AppCompat.Light.Dialog.Alert”. I usuń buttonBarNegativeButtonStyle & buttonBarPositiveButtonStyle. Dodaj także <item name = "colorAccent"> @ color / dashboard_red_color </item> w AlertDialogTheme. nd działa doskonale.
zephyr

3
To nie działa, gdy używam nowej biblioteki materiałów com.google.android.material:material:1.0.0-beta01i używam Theme.MaterialComponents.Light.Dialog.Alert
Sanjeev

2
@LX zaktualizowała odpowiedź, dodając motyw komponentów materiałowych
Alexander Perfilyev

120

Kolor przycisków i innego tekstu można również zmienić za pomocą motywu:

wartości-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>

Wynik:

Dialog Selektor dat


1
Obecnie nie znam sposobu, aby zmienić tylko kolor pola wyboru lub kolor przycisku. Akcent kolorystyczny zmienia ich obu.
peceps

4
Podobało mi się to podejście, ale wydaje mi się, że odpowiedź na stackoverflow.com/a/29810469/2291 jest nieco czystszym sposobem na zrobienie tego.
Jon Adams

12
Aby to zadziałało w moim projekcie, musiałem usunąć android:część zi android:alertDialogThemez android:colorAccent.
zakaz geoinżynierii

2
Posiadanie prefiksu android: na wartościach zależy od tego, gdzie umieścisz style.xml, w wartościach lub w wartościach-vXX
peceps

1
Aby to działało z AppCompat i prostym folderem wartości, po prostu postępuj zgodnie ze zmianami sugerowanymi przez @ ban-geoengineering
Felix

94

Najprostszym rozwiązaniem jest:

dialog.show(); //Only after .show() was called
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(neededColor);
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(neededColor);

4
Te pola nie powinny być przywoływane ze zmiennej niestatycznej, powinny być AlertDialog.BUTTON_NEGATIVEitd.
Joe Maher,

To był najlepszy i najprostszy sposób na zrobienie tego. Zwróć uwagę, że nie użyłem „tworzenia”, a raczej chwyciłem okno dialogowe po show (). Podobnie jak AlertDialog dialog = builder.show ();
Stephen McCormick

2
Chociaż to rozwiązanie może działać, logicznie jest błędne. To, co się tutaj dzieje, to najpierw wyświetlenie okna dialogowego, a następnie zmiana jego wyglądu. W zależności od podstawowej implementacji (która może ulec zmianie w czasie) i wydajności urządzenia, teoretycznie można było zobaczyć „migotanie”, gdy użytkownik zobaczy okno dialogowe, a następnie szybko zmienić jego wygląd.
trungdinhtrong

31

Istnieją dwa sposoby zmiany koloru przycisku dialogowego.

Podstawowy sposób

Jeśli chcesz po prostu zmienić działanie, napisz poniższe dwa wiersze po alertDialog.show();

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

Zalecana

Zalecam dodanie motywu AlertDialogw programie, styles.xmlaby nie trzeba było wielokrotnie pisać tego samego kodu w każdym wywołaniu działania / dialogu. Możesz po prostu utworzyć styl i zastosować ten motyw w oknie dialogowym. Więc kiedy chcesz zmienić kolor okna AlertDialog, po prostu zmień kolor w styles.xml, a wszystkie okna dialogowe zostaną zaktualizowane w całej aplikacji.

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

I zastosuj motyw w AlertDialog.Builder

AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AlertDialogTheme);

Ta odpowiedź jest najczystsza, ale wciąż jest poprawna.
Big_Chair

11

Jeśli chcesz zmienić kolor tekstu przycisków (pozytywny, negatywny, neutralny) po prostu dodaj do własnego stylu okna dialogowego:

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

Twój styl okna dialogowego musi więc wyglądać następująco:

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

Kolor przycisków i innego tekstu można również zmienić za pomocą appcompat:


Theme.AppCompat.Light.Dialog.Alert działa ładnie, aby zmienić kolor przycisku na biały.
Leo K.

6
  1. W motywie / stylu aplikacji dodaj następujące wiersze:

    <item name="android:buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
    <item name="android:buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
    <item name="android:buttonBarNeutralButtonStyle">@style/NeutralButtonStyle</item>
  2. Następnie dodaj następujące style:

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

Użycie tej metody sprawia, że ​​nie trzeba ustawiać motywu w konstruktorze AlertDialog.


4

Na marginesie:

Kolory przycisków (i całego stylu) zależą również od aktualnego motywu, który może się różnić w przypadku użycia jednego z nich

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

lub

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

(Lepiej użyć drugiego)


3

Oto jak to robisz: Prosty sposób

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

1

dla mnie było inaczej, użyłem motywu przycisku

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

i ponieważ

android: textColor

był tam biały… nie widziałem żadnego tekstu na przycisku (przyciski dialogowe to w zasadzie również przyciski). tam idziemy, zmieniliśmy to, naprawiliśmy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.