I am using animated vectors from Support Library 23.2.0, like this:
compile 'com.android.support:support-vector-drawable:23.2.0'
compile 'com.android.support:animated-vector-drawable:23.2.0'
I am trying to animate "pathData" (morphing lines one to another). My code looks like this.
drawable/ic_done.xml:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:name="tick"
android:pathData="M4.8,12L9,16.2L20,8"
android:strokeColor="#FF000000" />
</vector>
drawable/ic_done_animated.xml:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:drawable="@drawable/ic_done">
<target
android:name="tick"
android:animation="@animator/tick_path_animation" />
</animated-vector>
animator/tick_path_animation.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="200"
android:propertyName="pathData"
android:valueFrom="M4.8,12L4.8,12L4.8,12"
android:valueTo="M4.8,12L9,16.2L9,16.2"
android:valueType="pathType" />
<objectAnimator
android:duration="200"
android:propertyName="pathData"
android:valueFrom="M4.8,12L9,16.2L9,16.2"
android:valueTo="M4.8,12L9,16.2L20,8"
android:valueType="pathType" />
</set>
Java code:
ImageView vImgAnimated = findByViewId(R.id.img);
AnimatedVectorDrawableCompat animatedVector = AnimatedVectorDrawableCompat.create(getContext(), R.drawable.ic_done_animated);
vImgAnimated.setImageDrawable(animatedVector);
animatedVector.start();
It works well on newer device with API level 21 but I have a problem on device with API level 16:
java.lang.NumberFormatException: Invalid int: "M4.8,12L4.8,12L4.8,12"
at java.lang.Integer.invalidInt(Integer.java:138)
at java.lang.Integer.parse(Integer.java:375)
at java.lang.Integer.parseInt(Integer.java:366)
at com.android.internal.util.XmlUtils.convertValueToInt(XmlUtils.java:123)
at android.content.res.TypedArray.getInt(TypedArray.java:254)
at android.animation.AnimatorInflater.loadAnimator(AnimatorInflater.java:258)
at android.animation.AnimatorInflater.loadObjectAnimator(AnimatorInflater.java:161)
at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:117)
at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:126)
at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:93)
at android.animation.AnimatorInflater.loadAnimator(AnimatorInflater.java:72)
at android.support.graphics.drawable.AnimatedVectorDrawableCompat.inflate(AnimatedVectorDrawableCompat.java:377)
at android.support.graphics.drawable.AnimatedVectorDrawableCompat.createFromXmlInner(AnimatedVectorDrawableCompat.java:162)
at android.support.graphics.drawable.AnimatedVectorDrawableCompat.create(AnimatedVectorDrawableCompat.java:142)
According to an article android-support-library-232 the animated vectors (AnimatedVectorDrawableCompat) should be supported back to API level 11.
It looks like it fails while reading valueFrom attribute from tick_path_animation.xml. This attribute type "pathType" is probably not supported (yet?). Any idea how to solve this?
Load the Animated Vector Drawable in Android Studioxml file into the res/drawable folder of your Android Studio project. As it is Vector Drawable, you could put any width and height you want. If you put wrap_content , it will be per the size of the Vector Drawable, which in our case is 24dp . Now, you're done!
The drawback is that they might take longer to draw, etc since there's more of parsing and drawing going on than just using a bitmap. This should although be neglectable if you keep your vectors simple.
A VectorDrawable is a vector graphic defined in an XML file as a set of points, lines, and curves along with its associated color information. The major advantage of using a vector drawable is image scalability.
the circular "flash" in the above animation (in the center of the image) is me pressing the screen to start the morph.
Inflating Drawable's
`VectorDrawable`
and `AnimatedVectorDrawable`
in this support library (`vector-compat`) can be inflated in this way:
getDrawable()
methods://This will only inflate a drawable with <vector> as the root element VectorDrawable.getDrawable(context, R.drawable.ic_arrow_vector); //This will only inflate a drawable with <animated-vector> as the root element AnimatedVectorDrawable.getDrawable(context, R.drawable.ic_arrow_to_menu_animated_vector); // This will inflate any drawable and will auto-fallback to the lollipop implementation on api 21+ devices ResourcesCompat.getDrawable(context, R.drawable.any_drawable);
If inflating the Drawable in java code, it is recommended to always use ResourcesCompat.getDrawable()
as this handles Lollipop fallback when applicable. This allows the system to cache Drawable ConstantState and hence is more efficient.
The library (`vector-compat`) has the following morph (bi-directional) animations :
API 16
phone:import com.wnafee.vector.compat.AnimatedVectorDrawable;
mdrawable = (AnimatedVectorDrawable) AnimatedVectorDrawable.getDrawable(this.getApplicationContext(), R.drawable.consolidated_animated_vector);
Look at the github README for vector-compat
here: https://github.com/wnafee/vector-compat
This will fix your problem (down to API 14
) if you merge it with your app module's build.gradle
dependencies
(usually at the end of file):
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
//Trying to FIX Binary XML file line #2: invalid drawable tag animated-vector
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:design:25.0.0'
//not needed
// compile 'com.android.support:support-vector-drawable:25.0.0'
compile 'com.wnafee:vector-compat:1.0.5'//*******holy grail *******https://github.com/wnafee/vector-compat
// Failed to resolve: com.android.support:support-animated-vector-drawable:25.0.0
//not needed
// compile 'com.android.support:support-animated-vector-drawable:25.0.0'
}
Sorry, this will not work with the current version of the Support Library(23.2.0).
See Chris Banes article.
There are also some limitations to what kind of things animated vectors can do when running on platforms < API 21. The following are the things which do not work currently on those platforms:
Path Morphing (PathType evaluator). This is used for morphing one path into another path.
Path Interpolation. This is used to defined a flexible interpolator (represented as a path) instead of the system defined ones like LinearInterpolator.
Move along path. This is rarely used. The geometry object can move around, along an arbitrary path.
So animating the pathData, or 'Path Morphing' isn't currently supported.
Update:
Frank's comment:
This is finally fixed in support lib 25.4.0 (June 2017): "Path morphing and path interpolation are supported in AnimatedVectorDrawableCompat"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With