2015-03-01 13 views
22

Mam VectorDrawable składa się z 9 prostokątów. Jest to zdefiniowane jako XML w folderze drawables. Mam ten zestaw jako tło dla ImageView, które zadeklarowałem w xml. android:src="@drawable/squares00" Chciałbym zmienić kolor jednego lub więcej kwadratów programowo w czasie wykonywania. Wiem, że jest sposób, aby to zrobić za pomocą animacji VectorDrawable. Ale zastanawiałem się, czy istnieje prostszy sposób dostępu do mojego vectorDrawable w java, aktualizując jego właściwości (ustawiając jeden lub więcej kolorów wypełnienia dla prostokątów), a następnie aktualizując obraz tła za pomocą zaktualizowanej VectoDrawable. Moim celem jest Android API 21 (lizak)Programowo aktualizować Android wektor Drawable

+3

czy masz ans? – Shreeshesh

+0

Musisz użyć wielu rysunków lub mieć możliwość animowania pojedynczego losowania. Dlaczego nie chcesz korzystać z AnimatedVectorDrawable? –

+0

opublikuj niestandardowe wyciągnięcia. to nam pomoże. –

Odpowiedz

17

W skrócie:

  1. Robisz nie mają bezpośredni dostęp do wewnętrznych elementów VectorDrawable.
  2. AnimatedVectorDrawable ma tylko dostęp do elementów wewnętrznych.
  3. Skorzystaj z AnimatedVectorDrawable, aby zasymulować to, czego potrzebujesz.

Long:

1. Nie masz dostępu

Patrząc na source code dla VectorDrawable pokaże, że wewnętrzna informacja elementy są przechowywane w wewnętrznej prywatny klasy państwowej VectorDrawableState . Jedyną metodą na odsłonięcie elementu wewnętrznego jest name , ale niestety jest to pakiet prywatny (domyślnie) - nie możesz go użyć (chyba że używasz refleksji).

2. AnimatedVectorDrawable ma dostęp

getTargetByName tylko jest tylko używany przez AnimatedVectorDrawable, jak możemy znaleźć przez searching for usages metody.

3. Zastosowanie AnimatedVectorDrawable

Więc teraz, że widzimy, że jest to jedyna dostępna opcja, na przykład, możemy spróbować wykonać następujące czynności, aby zmienić kolor elementu „rect2” od bieli do czerni:

change_color.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android"> 
    <objectAnimator 
     android:duration="0" 
     android:propertyName="fillColor" 
     android:valueFrom="@color/white" 
     android:valueTo="@color/black"/> 
</set> 

animation.xml:

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" 
     android:drawable="@drawable/vectordrawable" > 
    <target 
     android:name="rect2" 
     android:animation="@anim/change_color" /> 
</animated-vector> 

i użyj podejścia opisanego pod numerem here.

Uwaga

Jeśli powyższe nadal nie jest to opcja dla Ciebie, możesz spróbować wykonać następujące czynności:

  • skopiować cały VectorDrawable i dostosować go (nie testowane)
  • użyć refleksji dla getTargetByName, aby uzyskać wewnętrzny element. Najpierw musisz się upewnić, że obiekt jest mutate.
+0

Widzę prywatną metodę pakowania, o której wspomniałeś w VectorDrawable: 'Obiekt getTargetByName (nazwa ciągu) { return mVectorState.mVPathRenderer.mVGTargetsMap.get (name); } ' Wygląda na to, że mówisz, że jeśli użyję tej metody, to teoretycznie mogę wykonać animację obiektu na tym obiekcie (" cel "), aby zmienić kolor? Co masz na myśli mówiąc, że najpierw muszę "zmutować" obiekt? –

+1

Jeśli użyjesz odbicia dla getTargetByName, będziesz mógł uzyskać element zdefiniowany w XML według nazwy. Jednym z przykładów będzie typ VFullPath - który jest również klasą prywatną. Będziesz musiał manipulować nim, używając ponownie odbicia w polu mFillColor (aby zmienić kolor). Odnośnie mutata, musisz wywołać mutate() na samej szufladzie - która utworzy lokalną kopię stanu wewnętrznego. Zanim to zrobisz, wszystkie te same zestawy danych będą miały te same dane, aby poprawić wydajność. –

+0

Dzięki @Eyal. To ma sens. Nie możemy się doczekać kiedy udostępnią do tego publiczny interfejs API. Mogę na razie spróbować tego hackowania, ale używam teraz podglądu z RapahelJS jako obejścia. Czy pomieszałeś z biblioteką wsparcia, którą opracowują dla VectorDrawable, aby sprawdzić, czy to też będzie działać? https://android.googlesource.com/platform/frameworks/support/+/master/v7/vectordrawable/ –

0

Użyj tego library do bezpośredniego dostępu do wewnętrznych elementów. To jest implementacja tego answer

Powiązane problemy