Mam przycisk w moim działaniu i chciałbym, aby miał kolor akcentu mojego motywu. Zamiast tworzyć własne elementy do rysowania, tak jak musieliśmy to zrobić przed Lollipopem, naturalnie chciałbym użyć nowego backgroundTint
atrybutu.
<Button
android:id="@+id/btnAddCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent"
android:text="@string/addressInfo_edit_addCode" />
Niestety nie daje to efektu, przycisk pozostaje szary.
Próbowałem różnych wartości backgroundTintMode
, które niczego nie zmieniały.
Próbowałem też zrobić to programowo w mojej Aktywności, co niczego nie zmieniło.
addCodeView.findViewById(R.id.btnAddCode).setBackgroundTintList(
getResources().getColorStateList(R.color.accent));
Dlaczego mój odcień jest ignorowany?
EDYCJA: Żeby wyjaśnić, rzeczywiście testuję na urządzeniu Lollipop. Inne widżety (np. EditText) są poprawnie i automatycznie przyciemniane.
Odpowiedzi:
Testowane na API 19 do API 27
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.AppCompatButton xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" style="@style/Widget.AppCompat.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/retry" android:textColor="@android:color/white" app:backgroundTint="@android:color/holo_red_dark" />
wytwarza wynik jako -
źródło
Złe wiadomości
Jak mówi BoD, zabarwienie tła przycisku w Lollipop 5.0 (poziom API 21) nie ma sensu.
Dobre wieści
Wydaje się, że Lollipop 5.1 (poziom API 22) naprawił ten problem, zmieniając btn_mtrl_default_shape.xml (między innymi): https://android.googlesource.com/platform/frameworks/base/+/6dfa60f33ca6018959ebff1efde82db7d2aed1e3%5E!/#F
Wspaniała wiadomość
Nowa biblioteka obsługi (wersja 22.1+) dodaje obsługę odcieni kompatybilną wstecz do wielu komponentów, w tym AppCompatButton !
Niestety
android:backgroundTint
właściwość nadal nie działa (może robię coś źle) - więc musisz ustawićColorStateList
kod używającsetSupportBackgroundTintList()
. Byłoby naprawdę miło widziećandroid:backgroundTint
wsparcie w przyszłości. Aktualizacja : Marcio Granzotto skomentował, żeapp:backgroundTint
działa na AppCompatButton! Zauważ, że takapp:
nie jestandroid:
, ponieważ znajduje się w aplikacji / bibliotece.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <AppCompatButton android:id="@+id/mybutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Testing, testing" app:backgroundTint="#ff00ff"/> </LinearLayout>
Twoja aktywność automatycznie zawyżnie wartość
AppCompatButton
zamiast normalnej,Button
jeśli pozwolisz jej dziedziczyćAppCompatActivity
.public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); AppCompatButton v = (AppCompatButton) findViewById(R.id.mybutton); ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{0xffffcc00}); v.setSupportBackgroundTintList(csl); } }
Powinieneś oczywiście pobrać
ColorStateList
z zasobu koloru, ale byłem leniwy, więc ...Aha, i nie zapomnij oprzeć motywu aplikacji na jednym z
Theme.AppCompat
motywów, w przeciwnym razie widoki kompatybilności będą bardzo, bardzo smutne ...;)To zadziałało zarówno na 2.3.7 (Gingerbread MR1), jak i 5.0 (Lollipop „Classic”).
źródło
colorButtonNormal
z AppCompat 22.1.1 (ustawienie motywu tylko dla przycisków), działa u mnie na 4.4.4 i 5.1.new ColorStateList(new int[][]{new int[0]}, new int[]{0xffffcc00});
ty możesz pisać bardziej zwięźleColorStateList.valueOf(0xffffcc00);
.Wydaje się, że zabarwienie rysowanego tętnienia jest bez znaczenia (a domyślnym tłem przycisku jest rysowanie tętnienia).
W rzeczywistości, po obejrzeniu domyślnego przycisku platformy do rysowania, znalazłem „prawidłowy” sposób, aby to zrobić: Musisz to zdefiniować w swoim motywie:
<item name="android:colorButtonNormal">@color/accent</item>
(Oczywiście dotyczy to tylko poziomu 21+.)
Ostrzeżenie: ponieważ jest to zdefiniowane w motywie, spowoduje to użycie danego koloru dla wszystkich przycisków (przynajmniej wszystkich przycisków w działaniach wykorzystujących ten motyw).
Jako bonus możesz również zmienić kolor tętnienia, definiując to:
<item name="android:colorControlHighlight">@color/accent_ripple</item>
źródło
colorControlHighlight
zmieniłoby jednak wiele innych widżetów. Cieszę się, że to rozpracowałeś.Aby rozwiązać problemy związane z przyciemnianiem w systemie Android 5.0.x, używam czegoś takiego:
public static void setButtonTint(Button button, ColorStateList tint) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP && button instanceof AppCompatButton) { ((AppCompatButton) button).setSupportBackgroundTintList(tint); } else { ViewCompat.setBackgroundTintList(button, tint); } }
Używa metody wsparcia tylko dla API 21 i ViewCompat dla wszystkich innych przypadków.
źródło
if (view instanceof TintableBackgroundView) { ((TintableBackgroundView) view).setSupportBackgroundTintList(tint); } else { ViewCompat.setBackgroundTintList(view, tint); }
Zwykle robię to dynamicznie za pomocą PorterDuff:
Możesz sprawdzić różne tryby mieszania tutaj i ładne przykłady tutaj .
źródło
Po prostu użyj
app:backgroundTint
zamiastandroid:backgroundTint
, odcień zacznie obowiązywać poniżej Lollipopa. Powodem jestAppCompatActivity
użycieAppCompatViewInflater
automatycznej zmiany Button lub TextView na AppCompatButton lub AppCompatTextView, a następnieapp:backgroundTint
zastosowanie.W moim projekcie wykorzystałem to, zadziałało.
źródło
Myślę, że musisz
android:background
się przygotowaćandroid:backgroundTint
pracy.Aby być dokładniejszym, przypuszczam, że nie można ustawić
backgroundTint
domyślnego tła przycisku z motywów Material, które jest zdefiniowane jako plikRippleDrawable
.źródło
Podobny problem został zgłoszony w Google https://code.google.com/p/android/issues/detail?id=201873
Ale po wydaniu biblioteki obsługi Androida, wersja 23.2.1 (marzec 2016) Ten błąd został rozwiązany.
Problem: FloatingActionButton.setBackgroundTintList (tinta @Nullable ColorStateList) nie zmienia już koloru tła
zaktualizuj bibliotekę pomocy do
Android Support Library to 23.2.1
Użyj biblioteki wsparcia projektowania (23.2.1) i appcompatwidgets, jak poniżej
Material Design dla urządzeń Pre-Lollipop :
Biblioteka obsługi Androida 22.1 :
źródło
Po prostu użyj app: backgroundTint zamiast android: backgroundTint
źródło
Jeśli spojrzymy na kod źródłowy Support Library, zobaczymy, że normalnie zabarwia to znane przyciski, ale jeśli zmienimy kształt naszego przycisku (mam okrągły przycisk), odcień nie działa poprawnie w api <= 21. Widzimy również, że TintManager stał się klasą publiczną (appcompat-v7: 23.1.1), więc możemy pobrać ColorStateList z domyślnego kształtu przycisku (który jest przyciemniony w wersji 5.0) dla bieżącego motywu (więc nie musimy tworzyć tablicy kolorów):
Context c = ...; // activity AppCompatButton ab = ...; // your button // works ok in 22+: if (Build.VERSION.SDK_INT <= 21) { // default appcompat button, that is tinted ok with current theme colors "abc_btn_default_mtrl_shape": // ColorStateList tint = TintManager.get(c).getTintList(R.drawable.abc_btn_default_mtrl_shape); // Appcompat 23.2 change: ColorStateList tint = AppCompatDrawableManager.get().getTintList(c, R.drawable.abc_btn_default_mtrl_shape); ab.setSupportBackgroundTintList(tint); }
źródło
Ponieważ atrybut
backgroundTint
jest używany tylko na poziomie interfejsu API 21 i wyższychźródło
Należy pamiętać, że najbardziej zaktualizowana biblioteka z recyklingiem może spowodować ten błąd.
To polecenie
sendBtnView.setBackgroundTintList(colorState)
działał doskonale w przeszłości, ale przestań dla mnie działać. po badaniach okazuje się, że przyczyną jest biblioteka dodana do zależności gradle:
compile 'com.android.support:recyclerview-v7:+'
Próbowałem więc zmienić to na 23.02.1, tak jak było to zalecane tutaj w poście Amit Vaghela. Zmieniłem się
compile 'com.android.support:recyclerview-v7:23.02.1'
Ale błąd gradle powiedział, że recyclinglerview lib nie ma tej wersji (23.02.1) (gradle nie mógł jej znaleźć w Jcenter raw.github lub repo).
Następnie, ponieważ wiedziałem, że komenda setBackgroundTintList działała dobrze w przeszłości z wersją 22.02.0 'we wszystkich innych bibliotekach, które mam w zależnościach gradle. więc zmieniam to na:
compile 'com.android.support:recyclerview-v7:22.02.0'
A teraz znowu działa.
źródło
Nie jestem pewien, czy jest to zalecane, ale możesz spróbować tego:
Drawable newDrawable = mBtnAction.getBackground(); // obtain Bg drawable from the button as a new drawable DrawableCompat.setTint(newDrawable, mActivity.getHomeTobBarBGColor()); //set it's tint mBtnAction.setBackground(newDrawable); //apply back to button
W ogólnym sensie to działa. Próbowałem,
ViewCompat
ale nie wydaje się działać poprawnie.źródło
możesz używać
backgroundTint
<android.support.design.button.MaterialButton
z"com.android.support:design:28.0.0-rc01"
wersjąźródło
Jeśli używasz Androidax, dodanie wersji z prefiksem i bez prefiksu rozwiązało problem w systemie Android 5.1:
<style name="Button_Primary"> <item name="android:layout_height">wrap_content</item> <item name="android:layout_width">wrap_content</item> <item name="android:backgroundTint">@color/button_primary_selector</item> <item name="backgroundTint">@color/button_primary_selector</item><!--needed for android 5--> </style>
Selektor button_primary znajduje się w
color
folderze z następującą zawartością:<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:local="http://schemas.android.com/apk/res-auto"> <item android:state_enabled="true" android:color="@android:color/holo_blue_dark" /> <item android:state_enabled="false" android:color="@android:color/darker_gray" /> </selector>
i zastosuj go na zwykłym przycisku
AppCompatActivity
<Button style="@style/Button_Primary"/>
źródło