Kolorowanie przycisków w Androidzie z Material Design i AppCompat

256

Przed dzisiejszą AppCompataktualizacją mogłem zmienić kolor przycisków w Androidzie L, ale nie w starszych wersjach. Po dołączeniu nowej aktualizacji AppCompat nie mogę zmienić koloru żadnej z wersji, kiedy próbuję, przycisk po prostu znika. Czy ktoś wie, jak zmienić kolor przycisku?

Poniższe zdjęcia pokazują, co chcę osiągnąć:

zdjęcie przedstawiające pożądany wynik

Biały przycisk jest domyślny, czerwony jest tym, czego chcę.

To właśnie robiłem wcześniej, aby zmienić kolor przycisków w styles.xml:

<item name="android:colorButtonNormal">insert color here</item>

i zrobić to dynamicznie:

button.getBackground().setColorFilter(getResources().getColor(insert color here), PorterDuff.Mode.MULTIPLY);

Zmieniłem też temat nadrzędny z @android:style/Theme.Material.Light.DarkActionBarnaTheme.AppCompat.Light.DarkActionBar

mail929
źródło
Próbowałem tego samego, ale nic nie zmieniło koloru przycisku. Usunąłem również Androida: z atrybutu, ponieważ pochodzi on z biblioteki wsparcia, a nie z przestrzeni nazw Androida
Informatic0re
Jeśli używasz Androida: colorButtonNormal z Androidem 5.0 to działa - ale wydaje się, że nie jest kompatybilne wstecz
Informatic0re
Tak, dokładnie tego doświadczyłem
mail929,
Doszedłem również do wniosku, że kolor akcentu nie zmienia koloru CheckBox, ale robi to w starszych wersjach
Informatic0re
plus jeden za tę dynamiczną metodę. :)
theapache64

Odpowiedzi:

222

Oficjalnie naprawiono w bibliotece pomocy technicznej wer. 22 (pt. 13 marca 2015 r.). Zobacz odpowiedni problem z kodem Google:

https://issuetracker.google.com/issues/37008632

Przykład użycia

theme.xml:

<item name="colorButtonNormal">@color/button_color</item>

v21 / theme.xml

<item name="android:colorButtonNormal">@color/button_color</item>
Powietrzny jeźdźca
źródło
17
Czy jest jakiś przykład, jak go używać? Jak ustawić kolory na jednym przycisku?
Zawiłości
3
@WindRider Mam jednak problem, chcę go użyć do tworzenia przycisków o różnych kolorach. Tworzę style Button.Red, Button.Green, wszystkie z nadrzędnym stylem bazowym Button. Ustawiłem element colorButtonNormal na żądany kolor, ustawiłem go jako motyw przycisku. Niestety koloruje tylko przyciski dla 21. Poniżej nie zastępuje colorButtonNormal zdefiniowanego w motywie.
dominik4142
71
Z AppCompat 22.1.1 działa dla mnie także w 2.3.7, 4.4.4 i 5.1 tylko dla jednego przycisku: ustawianie przycisków android:theme="@style/ColoredButton"oraz w styles.xml <style name="ColoredButton" parent="Widget.AppCompat.Button"> <item name="colorButtonNormal">@color/button_yellow</item> </style>
hunyadym
2
@hunyadym, dodanie motywu do przycisku powoduje przerwanie Kliknij z jakiegoś powodu. Sklasyfikowałbym to jako obejście, dopóki biblioteka projektu nie zapewni lepszego sposobu.
polany
3
@gladed: Wydaje się, że w twoim przypadku problemem jest ten błąd: code.google.com/p/android/issues/detail?id=62795#c1
hunyadym
148

Edytuj (22.06.2016):

Biblioteka Appcompat zaczęła obsługiwać przyciski materiałów po opublikowaniu oryginalnej odpowiedzi. W tym poście możesz zobaczyć najłatwiejszą implementację podniesionych i płaskich przycisków.

Oryginalna odpowiedź:

Ponieważ ten AppCompat nie obsługuje jeszcze przycisku, możesz używać xml jako tła. Aby to zrobić, rzuciłem okiem na kod źródłowy Androida i znalazłem powiązane pliki do stylizacji przycisków materiałów.

1 - Spójrz na oryginalną implementację przycisku materiału ze źródła.

Spójrz na plik btn_default_material.xml w kodzie źródłowym Androida .

Możesz skopiować plik do folderu Drawable-v21 projektów. Ale nie dotykaj tutaj koloru attr. Plik, który musisz zmienić, to drugi plik.

drawable-v21 / custom_btn.xml

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
    <item android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>

2 - Uzyskaj kształt oryginalnego przycisku materiału

Jak sobie uświadamiacie, w tym rysunku można znaleźć kształt, który można znaleźć w tym pliku kodu źródłowego .

<inset xmlns:android="http://schemas.android.com/apk/res/android"
   android:insetLeft="@dimen/button_inset_horizontal_material"
   android:insetTop="@dimen/button_inset_vertical_material"
   android:insetRight="@dimen/button_inset_horizontal_material"
   android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
    <corners android:radius="@dimen/control_corner_material" />
    <solid android:color="?attr/colorButtonNormal" />
    <padding android:left="@dimen/button_padding_horizontal_material"
             android:top="@dimen/button_padding_vertical_material"
             android:right="@dimen/button_padding_horizontal_material"
             android:bottom="@dimen/button_padding_vertical_material" />
</shape>

3 - Uzyskanie wymiarów przycisku materiału

W tym pliku znajdują się pewne wymiary z pliku , który można znaleźć tutaj . Możesz skopiować cały plik i umieścić go w folderze wartości . Jest to ważne, aby zastosować ten sam rozmiar (który jest używany w materiałowych przyciskach) do wszystkich przycisków

4 - Utwórz kolejny plik do rysowania dla starych wersji

W starszych wersjach powinieneś mieć inną rysownię o tej samej nazwie. Bezpośrednio umieszczam elementy w linii zamiast odwoływania się. Możesz odwoływać się do nich. Ale znowu najważniejszą rzeczą są oryginalne wymiary przycisku materiału.

drawable / custom_btn.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- pressed state -->
    <item android:state_pressed="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/PRESSED_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
    
    <!-- focused state -->
    <item android:state_focused="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/FOCUSED_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
    
    <!-- normal state -->
    <item>
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/NORMAL_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
</selector>

Wynik

Twój przycisk będzie miał efekt falowania na urządzeniach Lollipop. Stare wersje będą miały dokładnie ten sam przycisk, z wyjątkiem efektu marszczenia. Ale ponieważ udostępniasz drawable dla różnych stanów, będą one również reagować na zdarzenia dotykowe (jak w starym stylu).

eluleci
źródło
4
Tak, dokładnie. Jeśli używasz tego samego tła dla wszystkich przycisków i jeśli nie chcesz dodawać tego wielokrotnie, zdefiniuj styl przycisku w swoich stylach. Xml <style name = "ButtonStyle" parent = "android: Widget.Button"> < item name = "android: background"> ​​@ drawable / custom_btn </item> </style> i dodaj styl przycisku do motywu <item name = "android: buttonStyle"> @ style / ButtonStyle </item>
eluleci
1
Jak mogę dodać elewację do tego przycisku przed 21? jak rozumiem, powinienem dodać nowy kształt z cieniem pod przyciskiem, ale gdzie dokładnie powinienem go umieścić?
xakz
7
Bardzo denerwujące, że nie jest to obsługiwane po wyjęciu z pudełka
Sam
39
Całkowicie się z tobą zgadzam. Przycisk jest najczęściej używanym widżetem, ale nie jest zawarty w bibliotece obsługi materiałów. Zastanawiam się, co oni myśleli.
eluleci
1
Poza tym, zgodnie z twoim przewodnikiem, wydaje się, że tło wcale się nie pokazuje ...
JMRboosties
111

Zostało to ulepszone w wersji 23.0.0 biblioteki AppCompat, dodając więcej motywów, w tym

Widget.AppCompat.Button.Colored

Przede wszystkim uwzględnij zależność appCompat, jeśli jeszcze tego nie zrobiłeś

compile('com.android.support:appcompat-v7:23.0.0') {
    exclude group: 'com.google.android', module: 'support-v4'
}

teraz, ponieważ musisz używać wersji v23 aplikacji zgodnej, musisz również kierować reklamy na SDK-v23!

    compileSdkVersion = 23
    targetSdkVersion = 23

W Twoim values/theme

<item name="android:buttonStyle">@style/BrandButtonStyle</item>

W Twoim values/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>

W Twoim values-v21/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="android:colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>

Ponieważ motyw przycisku jest oparty na Widget.AppCompat.Button.ColoredKolor tekstu na przycisku jest domyślnie biały!

ale wydaje się, że występuje problem po wyłączeniu przycisku, przycisk zmieni kolor na jasnoszary, ale kolor tekstu pozostanie biały!

obejściem tego problemu jest specjalne ustawienie koloru tekstu na przycisku na biały! jak zrobiłem w stylu pokazanym powyżej.

teraz możesz po prostu zdefiniować swój przycisk i pozwolić AppCompat zrobić resztę :)

<Button
        android:layout_width="200dp"
        android:layout_height="48dp" />

Stan niepełnosprawny Stan wyłączony

Włączony stan Włączony stan

Edytować:

Dodać <Button android:theme="@style/BrandButtonStyle"/>

Muhammad Alfaifi
źródło
19
To najlepszy sposób na zrobienie tego teraz! Możesz także użyć stylu na poszczególnych przyciskach za pomocą <Button android:theme="@style/BrandButtonStyle"/>. To musi być themeatrybutem i niestyle atrybut.
mohlendo
7
@Muhammad Alfaifi Czy masz do tego przykładowy projekt lub treść? Stworzyłem czysty projekt i to nie działa: github.com/Bresiu/ThemeTest . W kolorach przycisków Lolipop z kolorem akcentowanym i w API v16 przycisk pozostaje szary: i.imgur.com/EVwkpk2.png
Bresiu
4
To zadziałało tylko ode mnie przy określaniu atrybutu android: motyw. Nie mogłem zmusić stylu atrybutu do pracy z tagiem przycisku.
Ray Hunter,
8
Używając lib 23.1, to nie działało poprawnie, zawsze pokazywało kolor akcentu jako bg, a nie ten zdefiniowany, podczas próby ustawienia go na cały motyw
Patrick Favre
3
Ten sam problem tutaj, w wersji 23.1 wyłączony przycisk ma ten sam kolor, co przycisk włączony. bardzo frustrujące. ktoś to rozgryza?
AhmedW
63

W Bibliotece pomocy Android 22.1.0 Google poinformował o Buttonodcieniu. Tak więc innym sposobem dostosowania koloru tła przycisku jest użycie backgroundTintatrybutu.

Na przykład,

<Button
       android:id="@+id/add_remove_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:backgroundTint="@color/bg_remove_btn_default"
       android:textColor="@android:color/white"
       tools:text="Remove" />
Manabu-GT
źródło
1
Wreszcie! Wpis na
GuillermoMP
5
Dokumentacja mówi: „Będzie to automatycznie użyte, gdy użyjesz przycisku w swoich układach. Tej klasy powinno się używać tylko podczas pisania widoków niestandardowych”. developer.android.com/reference/android/support/v7/widget/… czy to oznacza, że ​​nie musimy ręcznie zmieniać wszystkich naszych układów i kodu Java?
Stephane
@Stephane nie, powinniśmy zmienić układ. chris.banes.me/2015/04/22/support-libraries-v22-1-0
Anton Holovin
NIESAMOWITE! Czy jest teraz AppCompatToggleButton, który pozwala zmienić tło ToggleButtons? Może mogę plagiatować kod ...
swooby
19
Niestety działa to tylko w API 21+. Atrybut android: backgroundTint nie działa w wersjach wcześniejszych niż Lollipop, nawet w bibliotece AppCompat. Tylko colorButtonNormal z motywu działa na wersji wcześniejszej niż Lollipop.
Timur_C
42

Aby obsługiwać kolorowe przyciski, użyj najnowszej biblioteki AppCompat (> 23.2.1 ) z:

inflate - XML

AppCompat Widget:

android.support.v7.widget.AppCompatButton

Styl AppCompat:

style="@style/Widget.AppCompat.Button.Colored"

NB! Aby ustawić niestandardowy kolor w xml: użyj attr: appzamiastandroid

(użyj alt+enterlub zadeklaruj xmlns:app="http://schemas.android.com/apk/res-auto"użycie app)

aplikacja : backgroundTint = "@ color / your_custom_color"

Przykład:

<android.support.v7.widget.AppCompatButton
     style="@style/Widget.AppCompat.Button.Colored"
     app:backgroundTint="@color/your_custom_color"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"     
     android:text="Colored Button"/>

lub ustaw programowo - JAVA

 ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
TouchBoarder
źródło
Twój kod Java działał dla mnie. A odpowiedź Mahometa Alfaifi pomogła ustawić kolor tekstu przycisku.
Micro
czy istnieje prosty sposób programowo ustawić odcień (nie w tle)?
sklepienie
Wspaniale! Działa również na 4.4.4! I stan selektora jest również utrzymywany całkiem dobrze!
sud007,
Według dokumentów : Jest to automatycznie używane podczas ustawiania przycisków w układach. Musisz tylko podać AppCompatButton podczas tworzenia niestandardowych widoków.
gMale
Co ciekawe, zmiany XML działały doskonale we fragmencie, ale nie w układzie Activity. Przyciski aktywności wykorzystywały tylko kolorAccent. Wersja programowa działała jednak.
Leon
25

Z najnowszej biblioteki Wsparcia można po prostu odziedziczyć ci od aktywności AppCompatActivity, więc będzie nadmuchać swój Buttonjak AppCompatButtoni okazją do KOLOR każdego pojedynczego przycisku na układ, który z korzystaniem z android:theme="@style/SomeButtonStyle", którym SomeButtonStylejest:

<style name="SomeButtonStyle" parent="@android:style/Widget.Button">
    <item name="colorButtonNormal">@color/example_color</item>
</style>

Pracowałem dla mnie w 2.3.7, 4.4.1, 5.0.2

Artem
źródło
Dzięki!!! Właśnie zmieniłem wartość nadrzędną dla „Widget.AppCompat.EditText”, ponieważ muszę zaktualizować styl EditText.
Juan Saravia
3
Dziękuję, pracowałeś też dla mnie. Upewnij się, że używasz, android:themea nie style. Możesz także dodać colorControlHighlighti colorControlActivated.
Rachel
nie działa, API 22, AppCompatActivity, motyw Material.Light
Andrey Uglev
1
@AndreyUglev spróbuj użyć Theme.AppCompat.Lightzamiast tego.
Artem
Cześć, zmienia pożądany kolor, ALE usuwa cienie.
Amio.io,
16

jeśli chcesz poniżej stylu

wprowadź opis zdjęcia tutaj

dodaj ten styl do swojego przycisku

style="@style/Widget.AppCompat.Button.Borderless.Colored"

jeśli chcesz tego stylu

wprowadź opis zdjęcia tutaj

dodaj poniższy kod

style="@style/Widget.AppCompat.Button.Colored"
Jinu
źródło
1
compile 'com.android.support:appcompat-v7:23.1.0'Musisz dodać.
Pratik Butani
1
ale pytanie brzmi, jak mieć przyciski materiałów w różnych kolorach, aby nie wszystkie miały podstawowy kolor motywu.
Apostrofix
15

Odpowiedź brzmi: TEMAT, a nie styl

Problem polega na tym, że kolor przycisku jest przyklejony do colorButtonNormal motywu. Próbowałem zmienić Styl na wiele różnych sposobów bez powodzenia. Więc zmieniłem motyw przycisku .

Utwórz motyw z colorButtonNormal i colorPrimary:

<style name="ThemeAwesomeButtonColor" parent="AppTheme">
    <item name="colorPrimary">@color/awesomePrimaryColor</item>
    <item name="colorButtonNormal">@color/awesomeButtonColor</item>
</style>

Użyj tego motywu w przycisku

<Button
        android:id="@+id/btn_awesome"
        style="@style/AppTheme.Button"
        android:theme="@style/ThemeAwesomeButtonColor"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_awesome"/>

„AppTheme.Button” może dowolnie rozszerzać styl przycisku, tak jak tutaj Używam podstawowego koloru dla koloru tekstu:

<style name="AppTheme.Button" parent="Base.Widget.AppCompat.Button">
    ...
    <item name="android:textColor">?attr/colorPrimary</item>
    ...
</style>

I dostaniesz przycisk w dowolnym kolorze, który chcesz zgodny z materiałem.

lonelyboycs
źródło
jakie inne atrybuty mogę dodać do stylów.
Sagar Nayak,
4

Właśnie utworzyłem bibliotekę Androida, która pozwala łatwo modyfikować kolor przycisku i kolor tętnienia

https://github.com/xgc1986/RippleButton

<com.xgc1986.ripplebutton.widget.RippleButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn"
    android:text="Android button modified in layout"
    android:textColor="@android:color/white"
    app:buttonColor="@android:color/black"
    app:rippleColor="@android:color/white"/>

Nie trzeba tworzyć stylu dla każdego przycisku, który ma mieć inny kolor, co pozwala na losowe dostosowanie kolorów

xgc1986
źródło
4

to działa dla mnie z appcompat-v7: 22.2.0 w Androidzie + 4.0

w twoim styles.xml

<style name="Button.Tinted" parent="Widget.AppCompat.Button">
    <item name="colorButtonNormal">YOUR_TINT_COLOR</item>
    <item name="colorControlHighlight">@color/colorAccent</item>
    <item name="android:textColor">@android:color/white</item>
</style>

w pliku układu

<Button
    android:id="@+id/but_next"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/but_continue"
    android:theme="@style/Button.Tinted" />
ingyesid
źródło
Cześć, zmienia pożądany kolor, ALE usuwa cienie.
Amio.io,
Cześć znowu, widzę. To jest teraz właściwe zachowanie.
Amio.io,
Jak możesz to zrobić w Javie?
Micro
@MicroR sprawdź odpowiedź powyżej.
ingyesid
4

Układ:

<android.support.v7.widget.AppCompatButton
  style="@style/MyButton"
  ...
  />

styles.xml:

<style name="MyButton" parent="Widget.AppCompat.Button.Colored">
  <item name="backgroundTint">@color/button_background_selector</item>
  <item name="android:textColor">@color/button_text_selector</item>
</style>

color / button_background_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#555555"/>
    <item android:color="#00ff00"/>
</selector>

color / button_text_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#888888"/>
    <item android:color="#ffffff"/>
</selector>
BArtWell
źródło
3

Dla tych, którzy używają ImageButtontutaj, możesz to zrobić:

W style.xml:

<style name="BlueImageButton" parent="Base.Widget.AppCompat.ImageButton">
    <item name="colorButtonNormal">@color/primary</item>
    <item name="android:tint">@color/white</item>
</style>

w v21 / style.xml:

<style name="BlueImageButton" parent="Widget.AppCompat.ImageButton">
    <item name="android:colorButtonNormal">@color/primary</item>
    <item name="android:tint">@color/white</item>
</style>

Następnie w pliku układu:

<android.support.v7.widget.AppCompatImageButton
    android:id="@+id/my_button"
    android:theme="@style/BlueImageButton"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:layout_gravity="center_vertical"
    android:src="@drawable/ic_check_black_24dp"
    />
Micro
źródło
Pomogło to .... Wydaje mi się, że ważne jest, aby zastosować styl przycisku jako motyw zamiast stylu w widżecie Przycisk. Zastosowałem to pod stylem = "@ style / BlueImageButton" i to nie zadziałało
velval
3

Jeśli używasz rozwiązania stylu z colorButtonNormal , nie zapomnij odziedziczyć po Widget.AppCompat.Button.Colored aby efekt działał;)

Lubić

<style name="CustomButtonStyle" parent="Widget.AppCompat.Button.Colored">
      <item name="colorButtonNormal">@android:color/white</item>
</style>
didi.yeah
źródło
2

Kolejne proste rozwiązanie z wykorzystaniem AppCompatButton

<android.support.v7.widget.AppCompatButton
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     style="@style/Widget.AppCompat.Button.Colored"
     app:backgroundTint="@color/red"
     android:text="UNINSTALL" />
Hanzyusuf
źródło
2

Posługiwać się:

android:backgroundTint="@color/customColor"

Lub nawet :

android:background="@color/customColor"

i to da niestandardowy kolor przyciskowi.

SuKu
źródło
1

Jeśli chcesz tylko przycisk „Płaski” materiał, możesz dostosować jego tło za pomocą atrybutu selectableItemBackground, jak wyjaśniono tutaj .

kiruwka
źródło
Jeśli nie chcesz zmieniać żadnego z kolorów „odcień” lub wybranych kolorów, jest to zdecydowanie łatwe rozwiązanie, aby nadal otrzymywać informacje zwrotne za pomocą kolorowych przycisków. Dzięki!
theblang
1

Aby zmienić kolor jednego przycisku

ViewCompat.setBackgroundTintList(button, getResources().getColorStateList(R.color.colorId));
Jaydeep Solanki
źródło
1

Dla mnie problem polegał na tym, że w Androidzie 5.0 android:colorButtonNormalnie miał żadnego efektu, a właściwie żaden element z motywu (jak android:colorAccent), ale na przykład w Androidzie 4.4.3. Projekt został skonfigurowany compileSdkVersioni targetSdkVersiondo 22, więc zrobiłem wszystkie zmiany jako @Muhammad Alfaifi sugessted, ale w końcu, Zauważyłem, że problem był buildToolsVersion , który nie został zaktualizowany. Po zmianie na 23.0.1 wszystko zaczyna działać prawie jak zwykle. Teraz android:colorButtonNormalnadal nie ma efektu, ale przynajmniej przycisk reaguje android:colorAccent, co jest dla mnie dopuszczalne.

Mam nadzieję, że ta wskazówka może komuś pomóc. Uwaga: zastosowałem styl bezpośrednio do przycisku, ponieważ przyciski android:theme=[...]również nie działały.

Bianca Daniciuc
źródło
Prawie znalazłeś 100% poprawny sposób korzystania z nowego @ style / Widget.AppCompat.Button.Colored;) - zobacz tę odpowiedź stackoverflow.com/a/35811157/19733911
podobny
1

Jeden ze sposobów, aby to zrobić, pozwala po prostu wskazać styl i NIE motywować WSZYSTKICH przycisków w aplikacji tak samo.
W themes.xml dodaj motyw

    <style name="Theme.MyApp.Button.Primary.Blue" parent="Widget.AppCompat.Button">
        <item name="colorButtonNormal">@color/someColor</item>
        <item name="android:textColorPrimary">@android:color/white</item>
    </style>

Teraz dodaj do styles.xml

    <style name="MyApp.Button.Primary.Blue" parent="">
        <item name="android:theme">@style/Theme.MyApp.Button.Primary.Blue</item>
    </style>

Teraz w swoim układzie po prostu wskaż STYL w Przycisku

    <Button
        ...
        style="@style/MyApp.Button.Primary.Blue"
        ...  />
Douglas „DK” Knudsen
źródło
1

AKTUALIZACJA

Użyj biblioteki obsługi projektu (23.2.0) i widżetów aplikacji, jak poniżej

W bibliotece pomocy technicznej Androida 22.1 :

Odbywa się to automatycznie podczas nadmuchiwania układów - zamieniając Button na AppCompatButton, TextView na AppCompatTextView itp., Aby upewnić się, że każdy może obsługiwać barwienie. W tej wersji te widżety rozpoznające zabarwienie są teraz publicznie dostępne, co pozwala zachować wsparcie barwienia, nawet jeśli trzeba podklasować jeden z obsługiwanych widżetów.

Pełna lista widżetów uwzględniających odcień:

AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView

Projekt materiału dla urządzeń sprzed wersji Lollipop :

AppCompat (znany również jako ActionBarCompat) początkowo był backportem interfejsu API ActionBar dla Androida 4.0 dla urządzeń działających na Gingerbread, zapewniając wspólną warstwę API nad implementacją backportowaną i implementacją frameworka. AppCompat v21 zapewnia interfejs API i zestaw funkcji, które są aktualne w systemie Android 5.0


Amit Vaghela
źródło
1

Jeśli chcesz używać stylu AppCompat , takiego jak Widget.AppCompat.Button , Base.Widget.AppCompat.Button.Colored itp., Musisz użyć tych stylów z kompatybilnymi widokami z biblioteki wsparcia.

Poniższy kod nie działa na urządzeniach z wersją wcześniejszą niż Lolipop:

<Button
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:theme="@style/Widget.AppCompat.Button" />

Aby włączyć style AppCompat, musisz użyć AppCompatButton:

<android.support.v7.widget.AppCompatButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:theme="@style/Widget.AppCompat.Button" />
farukcankaya
źródło
2
Czy widżety kompatybilne z aplikacjami nie są używane automatycznie podczas nadmuchiwania układów XML? Myślę, że ImageViewzostanie zastąpiony AppCompatImageViewi powinien być taki sam dla wszystkich widżetów, które mają odpowiednią AppCompatwersję.
d.aemon
Nie, jeśli nie kierujesz na ostatnią wersję docelową, musisz android.support.v7.widget.AppCompatImageViewjawnie zdefiniować .
farukcankaya
Co rozumiesz przez last target version@power?
d.aemon
1

Używam tego. Działa efekt marszczenia i cień przycisku kliknięcia.

style.xml

<style name="Button.Red" parent="Widget.AppCompat.Button.Colored">
    <item name="android:textColor">@color/material_white</item>
    <item name="android:backgroundTint">@color/red</item>
</style>

Przycisk układu:

<Button
        style="@style/Button.Red"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/close"/>
Zmierzyć
źródło
0

Właściwie nie chciałem zmieniać niestandardowych stylów przycisków, ale niestety już nie działały.

Moja aplikacja ma minSdkVersion 9 i wszystko działało wcześniej.

Nie wiem dlaczego, ale odkąd usunąłem Androida: przed przyciskiem Style wydaje się, że znów działa

teraz = działa:

<item name="buttonStyle">@style/ButtonmyTime</item>

before = tylko szare przyciski materiałowe:

<item name="android:buttonStyle">@style/ButtonmyTime</item>

Nie mam folderu spezial dla nowej wersji Androida, ponieważ moje przyciski są dość płaskie i powinny wyglądać tak samo we wszystkich wersjach Androida.

Może ktoś może mi powiedzieć, dlaczego musiałem usunąć „Androida:” ImageButton nadal działa z „Androidem”:

<item name="android:imageButtonStyle">@style/ImageButtonmyTimeGreen</item>
Stefan
źródło
0

Po 2 dniach szukania odpowiedzi, temat przycisku nie działał dla mnie w API <21.

Moim jedynym rozwiązaniem jest zastąpienie barwienia AppCompatButton nie tylko za pomocą podstawowego motywu aplikacji „colorButtonNormal”, ale także widoku tła.

public class AppCompatColorButton extends AppCompatButton {

    public AppCompatColorButton(Context context) {
        this(context, null);
    }

    public AppCompatColorButton(Context context, AttributeSet attrs) {
        this(context, attrs, android.support.v7.appcompat.R.attr.buttonStyle);
    }

    public AppCompatColorButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        if (TintManager.SHOULD_BE_USED) {
            setSupportBackgroundTintList(createButtonColorStateList(getContext(), attrs, defStyleAttr));
        }
    }

    static final int[] DISABLED_STATE_SET = new int[]{-android.R.attr.state_enabled};
    static final int[] FOCUSED_STATE_SET = new int[]{android.R.attr.state_focused};
    static final int[] PRESSED_STATE_SET = new int[]{android.R.attr.state_pressed};
    static final int[] EMPTY_STATE_SET = new int[0];

    private ColorStateList createButtonColorStateList(Context context, AttributeSet attrs, int defStyleAttr) {
        final int[][] states = new int[4][];
        final int[] colors = new int[4];
        int i = 0;

        final int themeColorButtonNormal = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
        /*TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.backgroundTint }, defStyleAttr, 0);
        final int colorButtonNormal = a.getColor(0, themeColorButtonNormal);*/
        TypedArray a = context.obtainStyledAttributes(attrs, android.support.v7.appcompat.R.styleable.View, defStyleAttr, 0);
        final int colorButtonNormal = a.getColor(android.support.v7.appcompat.R.styleable.View_backgroundTint, themeColorButtonNormal);
        a.recycle();
        final int colorControlHighlight = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorControlHighlight);

        // Disabled state
        states[i] = DISABLED_STATE_SET;
        colors[i] = ThemeUtils.getDisabledThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
        i++;

        states[i] = PRESSED_STATE_SET;
        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
        i++;

        states[i] = FOCUSED_STATE_SET;
        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
        i++;

        // Default enabled state
        states[i] = EMPTY_STATE_SET;
        colors[i] = colorButtonNormal;
        i++;

        return new ColorStateList(states, colors);
    }
}

Następnie możesz zdefiniować kolor przycisku w następujący sposób:

<com.example.views.AppCompatColorButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:backgroundTint="#ffff0000"
            app:backgroundTint="#ffff0000"
            android:text="Button"
            android:textColor="@android:color/white" />
Thomas G.
źródło
0

Ta odpowiedź SO pomogła mi dojść do odpowiedzi https://stackoverflow.com/a/30277424/3075340

Korzystam z tej metody narzędzia, aby ustawić odcień tła przycisku. Działa z urządzeniami sprzed wersji Lollipop:

// Set button background tint programmatically so it is compatible with pre-lollipop devices.
public static void setButtonBackgroundTintAppCompat(Button button, ColorStateList colorStateList){
    Drawable d = button.getBackground();
    if (button instanceof AppCompatButton) {
        // appcompat button replaces tint of its drawable background
        ((AppCompatButton)button).setSupportBackgroundTintList(colorStateList);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Lollipop button replaces tint of its drawable background
        // however it is not equal to d.setTintList(c)
        button.setBackgroundTintList(colorStateList);
    } else {
        // this should only happen if
        // * manually creating a Button instead of AppCompatButton
        // * LayoutInflater did not translate a Button to AppCompatButton
        d = DrawableCompat.wrap(d);
        DrawableCompat.setTintList(d, colorStateList);
        button.setBackgroundDrawable(d);
    }

}

Jak używać w kodzie:

Utility.setButtonBackgroundTintAppCompat(myButton,
ContextCompat.getColorStateList(mContext, R.color.your_custom_color));

W ten sposób nie musisz określać ColorStateList, jeśli chcesz tylko zmienić odcień tła i nic więcej poza utrzymaniem ładnych efektów przycisków, a co nie.

Micro
źródło
0

Ustawiłem android:textColorna@null moim przycisku tematu i to pomaga.

styles.xml

<style name="Button.Base.Borderless" parent="Widget.AppCompat.Button.Borderless.Colored">
    <item name="android:textColor">@null</item>
</style>

some_layout.xml

<Button
    style="@style/Button.Base.Borderless"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hint" />

Teraz kolor tekstu przycisku jest colorAccentzdefiniowany wAppTheme

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="colorAccent">@color/colorAccent</item>
    <item name="borderlessButtonStyle">@style/Button.Base.Borderless</item>
    <item name="alertDialogTheme">@style/AlertDialog</item>
</style>
Denis Rybnikov
źródło
0

jeśli używasz kotlin, możesz zobaczyć, że obsługiwane są wszystkie atrybuty z MaterialButton. Nie używaj atrybutu android: tło. MaterialButton zarządza własnym tłem do rysowania, a ustawienie nowego tła oznacza, że ​​kolor wyłączonego przycisku Materiał nie może dłużej gwarantować, że nowe atrybuty, które wprowadzi, będą działały poprawnie. Jeśli domyślne tło zostanie zmienione, przycisk Materiał nie może zagwarantować dobrze zdefiniowanego zachowania. W MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        buttonClick.setOnClickListener {
            (it as MaterialButton).apply {
                backgroundTintList = ColorStateList.valueOf(Color.YELLOW)
                backgroundTintMode = PorterDuff.Mode.SRC_ATOP
            }
        }
    }
}

At Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/constraintLayout"
    tools:context=".MainActivity">
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonNormal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="Material Button Normal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonTint"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:backgroundTint="#D3212D"
        android:text="Material Button Background Red"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonNormal" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonTintMode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:backgroundTint="#D3212D"
        android:backgroundTintMode="multiply"
        android:text="Tint Red + Mode Multiply"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonTint" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonClick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Click To Change Background"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonTintMode" />
</androidx.constraintlayout.widget.ConstraintLayout>

zasób: Przykład zmiany koloru przycisku materiału

Tienanhvn
źródło
0

jeśli chcesz to zrobić za pomocą kodu w dowolnym kolorze, użyj tego:

DrawableCompat.setTintList(button.getBackground(), ColorStateList.valueOf(yourColor));
Amir Hossein Ghasemi
źródło