programmatically update android Vector Drawable

后端 未结 3 1691
悲&欢浪女
悲&欢浪女 2020-12-03 16:39

I have a VectorDrawable consists of 9 rectangles. This is defined as an XML in the the drawables folder. I have this set as the background for an ImageView that I have dec

相关标签:
3条回答
  • 2020-12-03 17:20

    In short:

    1. You don't have a direct access to the inner elements in VectorDrawable.
    2. AnimatedVectorDrawable only has access to inner elements.
    3. Use AnimatedVectorDrawable to simulate what you need.

    Long:

    1. You don't have access

    Looking at the source code for VectorDrawable will show that the inner elements information is stored in an inner private state class VectorDrawableState. The only method to expose the inner element by name is getTargetByName, but unfortunately it is package private (default) - you can't use it (unless you use reflection).

    2. AnimatedVectorDrawable only has access

    getTargetByName is only being used by AnimatedVectorDrawable, as we can find by searching for usages of the method.

    3. Use AnimatedVectorDrawable

    So now that we see that this is the only available option, for example, we can try the following to change the color of element "rect2" from white to black:

    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>
    

    and use the approach described here.

    Note

    If the above is still not an option for you, you can try the following:

    • Copy the entire VectorDrawable and tweak it (not tested)
    • Use reflection for getTargetByName to get the inner element. You will need to make sure to mutate the object first.
    0 讨论(0)
  • 2020-12-03 17:24

    Try this library https://github.com/devendroid/VectorChildFinder

    val vector = VectorChildFinder(context, R.drawable.drawable_id, imageView)
    vector.findPathByName("path_name").fillColor = Color.RED
    
    <vector
        ...>
    
        <path
            android:name="path_name"
            android:fillColor="#000"
            android:pathData="..." />
    </vector>
    
    0 讨论(0)
  • 2020-12-03 17:37

    Use this library for direct access to the inner elements. It is implement this answer

    0 讨论(0)
提交回复
热议问题