2016-04-27 11 views
12

Android Studio w wersji 2.1, Gradle wersję 2.1.0, proszę mnie poprawić, jeśli zauważysz jakiekolwiek błędnych interpretacji :)Programowo zabarwić się Pomoc Vector

Jestem zagubiony wektorów nośnych w bibliotece wsparcia 23.3.0. W szczególności chciałbym programowo odcieńować przycisk obrazu, którego src jest zdefiniowany jako rysowany wektor. Z tego, co mogę powiedzieć, nie jest to możliwe na pre-Lollipop teraz.

Znam kilka podobnych wiadomości o zmianach: 23.2.0 announcement and changes:

Jako Android Wsparcia Biblioteka 23.3.0, wsparcie kanału alfa wektorowe mogą być ładowane tylko za pośrednictwem aplikacji: srcCompat lub setImageResource().

Czy powyższe oznacza, że ​​wektor plików XML można używać tylko pre-Lollipop poprzez srcCompat lub setImageResource(), a zatem nie może być dynamicznie przyciemniane?

Tu jest mój podstawowy przycisk obraz:

<ImageButton 
    android:id="@+id/nav_header_exit_community_button" 
    android:layout_width="48dp" 
    android:layout_height="48dp" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentRight="true" 
    android:background="@null"/> 

Prace nad lizak i nowszych:

Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp); 
    DrawableCompat.setTint(bg, headerTitleColor); 
    exitButton.setImageDrawable(bg); 

Próba tę wstępną lizaka rzuca: android.content.res.Resources$NotFoundException: File res/drawable/ic_exit_to_app_24dp.xml from drawable resource ID #0x7f0200bf

działa również na Lollipop i powyżej tylko

Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp); 
    DrawableCompat.setTint(bg, headerTitleColor); 
    exitButton.setImageResource(R.drawable.ic_exit_to_app_24dp); 

Powoduje to ten sam błąd na pre-Lollipop.

Jednak jeśli usunąć vectorDrawables.useSupportLibrary = true jak wskazał by Ian Lake here, z zamiarem posiadania narzędzia budowania automatycznego generowania PNG do wstępnego Lollipop urządzeń że PNG nie zabarwić się na pre-lizak, więc jestem z powrotem punkt wyjścia.

Próbowałem również określić wektor przez srcCompat i pobrać go programowo, ale nie sądzę, byłem w stanie to osiągnąć, nawet jeśli działa on po Lollipop, jeśli wektor jest określony przy użyciu src zamiast tego.

Więc sytuacja 23.3.0 wydaje się być:

  • Post-Lollipop: src i srcCompat zaakceptować wektorów, tylko src może być pobierane z widzenia jako rozciągliwej do barwienia programowo. Przywoływanie wektorów w kodzie jest możliwe za pomocą funkcji getDrawable, a one mogą być przyciemniane.

  • Pre-Lollipop: srcCompat akceptuje tylko wektory, nie można go pobrać programowo z widoku do barwienia. setImageResource może akceptować wektory, ale tylko jeśli vectorDrawables.useSupportLibrary = false i zabarwianie nie działa. Podobnie, odniesienia wektorów w kodzie nie są możliwe, chyba że vectorDrawables.useSupportLibrary = false i zabarwienie nie działa.

pracy we wszystkich wersjach przy użyciu PNG:

Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_nav_exit_community); 
    DrawableCompat.setTint(bg, headerTitleColor); 
    exitButton.setImageDrawable(bg); 

Uzupełnienie:

Technika ta działa również na post-Lollipop, ale jak inni na pre-Lollipop otrzymuję ciągnięcie, ale bez zabarwienia:

Drawable bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null); 
    DrawableCompat.setTint(bg, headerTitleColor); 
    exitButton.setImageDrawable(bg); 

rodzaju rozwiązanie:

Dzięki John's odpowiedź do tej pory tylko idiotoodporny sposób mogę wymyślić, aby zabarwić wektor support jest ustawiony filtr koloru na nim - oznacza to, że funkcja DrawableCompat.setTint() jest pozornie nie działa dla mnie, jeśli dany dannik jest wektorem pomocniczym. Nie jestem pewien, czy jest to prawdziwy błąd, oczekiwane zachowanie, czy robię coś złego!

Oto rozwiązanie Idę ze w tej chwili:

Drawable bg; 
    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 
     bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null); 
     exitButton.setColorFilter(headerTitleColor, PorterDuff.Mode.MULTIPLY); 
    } 
    else { 
     bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp); 
     DrawableCompat.setTint(bg, headerTitleColor); 
    } 
    exitButton.setImageDrawable(bg); 
+0

Czy to działa w przypadku korzystania z biblioteki Wektor Compat stworzyć swój drawble? tj. VectorDrawableCompat.create (getResources(), R.drawable.ic_action_add, null) – Kuffs

+0

Zaktualizowałem moją odpowiedź, wygląda na to, że jest to kolejna technika (!) do robienia tego samego rodzaju, ale zabarwianie jej nie działa na pre-L –

+0

to nie jest kolejna technika, tak powinno powstać 'VectorDrawableCompat' i jeśli przeczytasz' DrawableCompat' dokumenty, zobaczysz, że [to] (http://pastebin.com/CzEbnP9k) po prostu działa – pskink

Odpowiedz

26

przede wszystkim trzeba zastosować VectorDrawableCompat#create raz masz swoje Drawable musisz zadzwonić DrawableCompat#wrap:

Potencjalnie zawijanie do rysowania, dzięki czemu może być używane do barwienia na różnych poziomach interfejsu API za pomocą metod barwienia w tej klasie.

tak Twój kod będzie wyglądać następująco:

ImageView iv = .... 
Drawable d = VectorDrawableCompat.create(getResources(), R.drawable.ic_exit_to_app_24dp, null); 
d = DrawableCompat.wrap(d); 
DrawableCompat.setTint(d, headerTitleColor); 
iv.setImageDrawable(d); 
5

Można użyć setColorFilter metodę ImageView:

imageView.setColorFilter(headerTitleColor, android.graphics.PorterDuff.Mode.MULTIPLY);

+0

Na razie wydaje się to najlepszym rozwiązaniem, chociaż nie jestem z tego zadowolony! –