J'ai un VectorDrawable composé de 9 rectangles. Ceci est défini en tant que XML dans le dossier drawables. J'ai cet ensemble comme arrière-plan pour un ImageView que j'ai déclaré en XML. Android:src="@drawable/squares00"
Je voudrais changer la couleur d'un ou plusieurs carrés par programmation au moment de l'exécution. Je sais qu'il est possible de faire cela en utilisant des animations VectorDrawable. Mais je me demandais s’il existe un moyen plus simple d’accéder à mon vectorDrawable en Java, en mettant à jour ses propriétés (en définissant une ou plusieurs des couleurs de remplissage des rectangles), puis en mettant à jour le fond d’image avec le VectoDrawable mis à jour. Ma cible est Android API 21 (Lollipop)
En bref:
Longue:
1. Vous n'avez pas accès
En regardant le code source pour VectorDrawable , vous verrez que les informations relatives aux éléments internes sont stockées dans une classe interne _privateVectorDrawableState
. La seule méthode permettant d'exposer l'élément interne par nom est getTargetByName
, mais malheureusement, il s'agit du paquet privé (par défaut) - vous ne pouvez pas l'utiliser (à moins d'utiliser la réflexion).
2. AnimatedVectorDrawable n'a qu'un accès
getTargetByName
n'est utilisé que par AnimatedVectorDrawable , comme nous pouvons le trouver par en recherchant des usages de la méthode.
3. Utilisez AnimatedVectorDrawable
Donc, maintenant que nous voyons que c'est la seule option disponible, par exemple, nous pouvons essayer ce qui suit pour changer la couleur de l'élément "rect2" du blanc au noir:
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>
et utilisez l’approche décrite ici .
Remarque
Si ce qui précède n'est toujours pas une option pour vous, vous pouvez essayer les solutions suivantes:
getTargetByName
pour obtenir l'élément interne. Vous devrez d'abord vous assurer de mutate
l'objet.Utilisez cette bibliothèque pour un accès direct aux éléments internes. C'est mettre en œuvre ceci répondre