Barwienie do rysowania dla api <21

84

Czy możliwe jest zastosowanie barwienia do rysowania dla api <21?

<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_calendar"
    android:tint="@color/primary" />

Działa dobrze, ale tylko na urządzeniach z API21. Jakieś obejście dla urządzeń z niższym interfejsem API lub obsługi AppCompat? Nic nie mogę znaleźć.

MaTTo
źródło

Odpowiedzi:

106

Użyj w ten AppCompatImageViewsposób:

<android.support.v7.widget.AppCompatImageView
        android:id="@+id/my_appcompat_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/my_image"
        android:tint="#636363"
    />

Upewnij się, że masz najnowsze appcompat-v7wersje aplikacji build.gradle.

Przykład: compile 'com.android.support:appcompat-v7:25.0.0'w pliku build.gradle.

Sakiboy
źródło
66
Z AppCompatImageViewdokumentów: This will automatically be used when you use ImageView in your layouts. You should only need to manually use this class when writing custom views. developer.android.com/reference/android/support/v7/widget/… Tak więc użycie normalnego ImageViewukładu powinno działać dobrze.
Nimrod Dayan
1
Jak wspomniał @NimrodDayan powyżej, nie powinno to być konieczne. Otrzymuję raporty o android: tint nie działa na Samsung A5 i Moto G, jednak (używając appcompat-v7: 23.4.0), więc możliwe, że ImageViews nie są poprawnie zastępowane na niektórych urządzeniach.
Stephen Kidson
@StephenKidson, używam tej samej wersji appcompat i również napotkałem ten sam problem na urządzeniu nieznanej marki. Czy udało ci się to rozwiązać? Zastanawiam się, czy jest zgłoszony błąd w tym ...
Nimrod Dayan
4
To nie działało na emulatorze Android 4.0 używającym appcompat-v7: 25.1.0.
Peterdk
4
AppCompatImageView nie można używać wewnątrz widżetu. Użyj setColorFilter w ImageView.
Massimo
46

Możesz to osiągnąć za pomocą kodu źródłowego. Wcześniej barwienie nie było obsługiwane przez DrawableCompat. Zaczynając od biblioteki wsparcia 22.1 możesz to zrobić, ale musisz to zrobić w ten sposób:

Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));
Simon K. Gerges
źródło
18
Jeśli potrzebujesz obsługi odcieni w <21 interfejsach API, prawdopodobnie zechcesz użyć ContextCompat.getColor()zamiast getResources().getColor().
Sevastyan Savanyuk
22

Czy nie mógłbyś po prostu użyć ImageView do wyświetlenia swojego Drawable? android:tintdziała dobrze na starszych poziomach API.

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_calendar"
    android:tint="@color/primary"
    />
Jonik
źródło
2
Używam ImageView - aby wyświetlić w nim ikonę. Te ikony są częścią elementów w szufladzie nawigacji. Wybrany element w szufladzie nawigacji ma inny kolor, więc utworzyłem przyciemnioną każdą ikonę, a także selektor dla każdej ikony. I używam tego selektora dla mojej ikony. Selektor:<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:drawable="@drawable/ic_home_tinted" /> <item android:drawable="@drawable/ic_home" /> </selector>
MaTTo
@Orochi Spójrz na moją odpowiedź, ponieważ pochodzi ona bezpośrednio z blogów Google. Działa głównie tylko na Androidzie 5.0+, ale może działać na niektórych widżetach dla urządzeń z systemem starszym niż Android 5.0.
Jared Burrows,
@Orochi Będziesz musiał stworzyć własne widoki, aby „naśladować” ten sam efekt.
Jared Burrows,
1
Możesz użyć widoku obrazu, uczynić ikonę tak białą, jak to tylko możliwe i nadać jej dowolny kolor za pomocą iv.setColorFilter (yourColor, Mode.Multiply); Upewnij się, że importujesz android.graphics.PorterDuff.Mode
jb15613
3
Mam ten sam problem. Niestety odcień z selektorem nie działa z api <21
Luccas
17

Podobne pytanie zadano tutaj: https://stackoverflow.com/a/26533340/950427

Barwienie do rysowania w systemie Android jest obsługiwane tylko w systemie Android 5.0+ (API 21+). (Mówi się „ At the moment this is limited to coloring the action bar and some widgets.”).

Motyw

...

Po ustawieniu tych atrybutów AppCompat automatycznie propaguje ich wartości do atrybutów struktury w interfejsie API 21+. Spowoduje to automatyczne kolorowanie paska stanu i wpisu zadania Przegląd (ostatnie).

Na starszych platformach AppCompat emuluje motywy kolorów, jeśli to możliwe. W tej chwili ogranicza się to do kolorowania paska akcji i niektórych widżetów.

I

Barwienie widżetów

Podczas uruchamiania na urządzeniach z Androidem 5.0 wszystkie widżety są przyciemniane przy użyciu atrybutów motywów kolorystycznych, o których właśnie rozmawialiśmy.Istnieją dwie główne funkcje, które pozwalają na to w Lollipop: barwienie do rysowania i odwoływanie się do atrybutów motywu (w postaci? Attr / foo) w drawables.

AppCompat zapewnia podobne zachowanie we wcześniejszych wersjach Androida dla podzbioru widżetów interfejsu użytkownika:

Wszystko, co zapewnia pasek narzędzi AppCompat (tryby akcji, itp.) EditText Spinner CheckBox Przełącznik RadioButton (użyj nowego android.support.v7.widget.SwitchCompat) CheckedTextView Nie musisz robić nic specjalnego, aby te elementy działały, po prostu użyj tych elementów sterujących w Twoje układy jak zwykle, a AppCompat zrobi resztę (z pewnymi zastrzeżeniami; zobacz FAQ poniżej).

Źródła:

http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html

https://chris.banes.me/2014/10/17/appcompat-v21/

Jared Burrows
źródło
Dlaczego ten głos został odrzucony? To pochodzi z oficjalnej dokumentacji.
Jared Burrows
Odpowiedź jest nieaktualna. ImageViewobsługuje teraz również android:tintprzez AppCompat, jak w odpowiedzi @ Jonik.
Vicky Chijwani
@VickyChijwani Prześlij zmianę. Masz na myśli AppCompatImageView, że nie ImageView.
Jared Burrows
13

Teraz AppCompatImageView, AppCompatButton zastąpi ImageView, Button, aby obsługiwać odcień na urządzeniach z niższym interfejsem API. Sprawdź link, aby uzyskać więcej informacji AppCompatImageView , AppCompatButton

Ankit Singh
źródło
6

Do barwienia obrazów możesz użyć imageView.setColorFilter(int color). Działa to z API 8 i działało nad zabarwieniem mojego czarnego obrazu na wybrany kolor. To może zastąpić, setImageTintList()ale samo użycie android:tintpowinno również działać.

Peterdk
źródło
4

Użyj tej NameSpace
xmlns : app = "http://schemas.android.com/apk/res-auto"

a po tym, jak każdy android: tint, możesz zamienić na app: tint. To rozwiąże problem.

seinta
źródło
4

Trochę się spóźniłem, ale oto jak to zrobić.

val textInput = EditText(context)

val drawable = ContextCompat.getDrawable(context, R.drawable.your_drawable)
drawable?.let {
    myDrawable -> DrawableCompat.setTint(myDrawable, ContextCompat.getColor(context, R.color.your_color))
    textInput.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, myDrawable, null)
}
Zwariowany
źródło
1

Zrobi to tak, jak chcesz i powinno działać na wszystkich wersjach biblioteki obsługi systemu Android:

@JvmStatic
fun getTintedDrawable(inputDrawable: Drawable, @ColorInt color: Int): Drawable {
    val wrapDrawable = DrawableCompat.wrap(inputDrawable.mutate())
    DrawableCompat.setTint(wrapDrawable, color)
    DrawableCompat.setTintMode(wrapDrawable, Mode.SRC_IN)
    return wrapDrawable
}
programista Androida
źródło
1

Jeśli ktoś chce stworzyć nowy drawable (tin1, tint2 ..) spróbuj tego

<?xml version="1.0" encoding="utf-8"?>
<bitmap
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:src="@drawable/your_image"
  android:tint="@color/tint_color">
   </bitmap>
Ranjith Kumar
źródło