支持库中的 AnimatedVectorDrawable 和 "pathData" 的动画
AnimatedVectorDrawable in Support Library and animation of "pathData"
我正在使用 支持库 23.2.0 中的 动画矢量 ,像这样:
compile 'com.android.support:support-vector-drawable:23.2.0'
compile 'com.android.support:animated-vector-drawable:23.2.0'
我正在尝试为“pathData”设置动画(将一条线变形为另一条线)。我的代码看起来像这样。
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代码:
ImageView vImgAnimated = findByViewId(R.id.img);
AnimatedVectorDrawableCompat animatedVector = AnimatedVectorDrawableCompat.create(getContext(), R.drawable.ic_done_animated);
vImgAnimated.setImageDrawable(animatedVector);
animatedVector.start();
它在 API 级别 21 的较新设备上运行良好,但我在 API 级别 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)
根据一篇文章android-support-library-232,动画矢量 (AnimatedVectorDrawableCompat) 应支持回到 API 级别 11。
从 tick_path_animation.xml 读取 valueFrom 属性时似乎失败了。此属性类型 "pathType" 可能不受支持(还?)。知道如何解决这个问题吗?
抱歉,这不适用于当前版本的支持库 (23.2.0)。
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.
因此当前不支持对 pathData 或 'Path Morphing' 进行动画处理。
更新:
弗兰克的评论:
This is finally fixed in support lib 25.4.0 (June 2017): "Path
morphing and path interpolation are supported in
AnimatedVectorDrawableCompat"
上面动画中的圆形"flash"(在图像的中央)是我按下屏幕开始变形。
为 Drawable 充气
此支持库 (`vector-compat`) 中的 `VectorDrawable`
和 `AnimatedVectorDrawable`
可以这样膨胀:
- 调用静态
getDrawable()
方法:
//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);
如果在 java 代码中膨胀 Drawable,建议始终使用 ResourcesCompat.getDrawable()
,因为这会在适用时处理 Lollipop 回退。这允许系统缓存 Drawable ConstantState,因此效率更高。
库 (`vector-compat`) 具有以下变形(双向)动画:
播放-暂停变形动画
播放停止变形动画
Arrow-汉堡菜单变形动画
如您所见,我在 API 16
phone:
上生成了上面的图像
import com.wnafee.vector.compat.AnimatedVectorDrawable;
mdrawable = (AnimatedVectorDrawable) AnimatedVectorDrawable.getDrawable(this.getApplicationContext(), R.drawable.consolidated_animated_vector);
在此处查看 github README vector-compat
:https://github.com/wnafee/vector-compat
如果您将它与应用程序模块的 build.gradle
dependencies
(通常在文件末尾)合并,这将解决您的问题(下降到 API 14
):
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'
}
我正在使用 支持库 23.2.0 中的 动画矢量 ,像这样:
compile 'com.android.support:support-vector-drawable:23.2.0'
compile 'com.android.support:animated-vector-drawable:23.2.0'
我正在尝试为“pathData”设置动画(将一条线变形为另一条线)。我的代码看起来像这样。
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代码:
ImageView vImgAnimated = findByViewId(R.id.img);
AnimatedVectorDrawableCompat animatedVector = AnimatedVectorDrawableCompat.create(getContext(), R.drawable.ic_done_animated);
vImgAnimated.setImageDrawable(animatedVector);
animatedVector.start();
它在 API 级别 21 的较新设备上运行良好,但我在 API 级别 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)
根据一篇文章android-support-library-232,动画矢量 (AnimatedVectorDrawableCompat) 应支持回到 API 级别 11。
从 tick_path_animation.xml 读取 valueFrom 属性时似乎失败了。此属性类型 "pathType" 可能不受支持(还?)。知道如何解决这个问题吗?
抱歉,这不适用于当前版本的支持库 (23.2.0)。
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.
因此当前不支持对 pathData 或 'Path Morphing' 进行动画处理。
更新:
弗兰克的评论:
This is finally fixed in support lib 25.4.0 (June 2017): "Path morphing and path interpolation are supported in AnimatedVectorDrawableCompat"
上面动画中的圆形"flash"(在图像的中央)是我按下屏幕开始变形。
为 Drawable 充气
`VectorDrawable`
和 `AnimatedVectorDrawable`
可以这样膨胀:
- 调用静态
getDrawable()
方法:
//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);
如果在 java 代码中膨胀 Drawable,建议始终使用 ResourcesCompat.getDrawable()
,因为这会在适用时处理 Lollipop 回退。这允许系统缓存 Drawable ConstantState,因此效率更高。
库 (`vector-compat`) 具有以下变形(双向)动画:
如您所见,我在
API 16
phone:上生成了上面的图像
import com.wnafee.vector.compat.AnimatedVectorDrawable;
mdrawable = (AnimatedVectorDrawable) AnimatedVectorDrawable.getDrawable(this.getApplicationContext(), R.drawable.consolidated_animated_vector);
在此处查看 github README vector-compat
:https://github.com/wnafee/vector-compat
如果您将它与应用程序模块的 build.gradle
dependencies
(通常在文件末尾)合并,这将解决您的问题(下降到 API 14
):
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'
}