Precise control over Androids VectorDrawable animations(精确控制 Android 的 VectorDrawable 动画)
问题描述
更新:找到解决方案!向下滚动查看我接受的答案!
我想为一张图像的多个元素制作动画并将动画链接到 ViewPagers 位置(因此多个元素会根据被拖动的当前页面进行变形或飞入/飞出).
那么,有没有办法精确控制动画的当前帧呢?例如,假设我有这个集合:
<?xml version="1.0" encoding="utf-8"?><设置 xmlns:android="http://schemas.android.com/apk/res/android">
动画矢量文件:
<目标android:name="plus_button"android:animation="@anim/pre_signup_1_plus_container"/><目标机器人:名称=加号"android:animation="@anim/pre_signup_1_plus_sign"/></动画矢量>
运行动画的Java代码:
ImageView mImage1 = (ImageView) findViewById(R.id.image_1);AnimatedVectorDrawableCompat 动画 = (AnimatedVectorDrawableCompat) mImage1.getDrawable();动画.start();
有没有办法像 setCurrentDuration(400)
这样控制动画,它可能会将动画的当前状态设置为一半?也许有一种方法可以将该矢量可绘制对象拆分为图层并以编程方式对其进行动画处理?提前致谢!
看起来可以访问 VectorDrawableCompat
中的路径和组,并根据需要对它们进行动画/变形!p>
经过一番研究,我最终从 android.support.graphics.drawable
包中复制了以下类:AndroidResources
、PathParser
、TypedArrayUtils
、VectorDrawableCommon
和 VectorDrawableCompat
.
接下来,我们需要在 VectorDrawableCompat
类中公开以下方法和类:getTargetByName
、VGroup
和 VFullPath代码>.
接下来在 VectorDrawableCompat
类中移除检查 Android 版本 (Build.VERSION.SDK_INT >= 23
) 的块.不知道为什么,但如果你不这样做,动画将无法在 android API 23 及更高版本上运行(需要更多研究).
我可能遗漏了一些私有方法,但如果遇到问题,只需将它们公开即可.
所以,现在我们可以访问 VectorDrawable
的图层了!这是一个根据 ViewPager
的位置缩放矢量组的小示例:
<?xml version="1.0" encoding="utf-8"?><向量 xmlns:android="http://schemas.android.com/apk/res/android"安卓:宽度=276dp"机器人:高度=359dp"android:viewportWidth="276"android:viewportHeight="359"><组安卓:pivotX="205.5"安卓:pivotY="214.5"android:name="my_group"><路径android:strokeColor="#4D394B"机器人:strokeWidth =7"机器人:strokeLineJoin="斜角"安卓:fillColor="#1ED761"android:pathData="M206.5,180 C186.9,180,171,195.9,171,215.5 S186.9,251,206.5,251C226.1,251,242,235.1,242,215.5 S226.1,180,206.5,180 Z"/><路径安卓:fillColor="#4D394B"android:pathData="M210,211 L210,190 L202,190 L202,211 L181,211 L181,219 L202,219 L202,241 L210,241L210,219 L232,219 L232,211 Z"/></组></矢量>
这是用于动画组的代码:
ImageView myImageView;VectorDrawableCompat.VGroup myVectorGroup;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_welcome);myImageView = (ImageView) findViewById(R.id.image_1);VectorDrawableCompat vectorDrawable = VectorDrawableCompat.create(getResources(), R.drawable.my_vector_drawable, null);vectorDrawable.setAllowCaching(false);//重要的是允许图像更新myVectorGroup = (VectorDrawableCompat.VGroup) vectorDrawable.getTargetByName("my_group");myImageView.setImageDrawable(vectorDrawable);mViewPager = (ViewPager) findViewById(R.id.pager);mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@覆盖public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {if(myVectorGroup != null && 位置 < 1) {myVectorGroup.setScaleX(1f - positionOffset);myVectorGroup.setScaleY(1f - positionOffset);myImageView.invalidate();}}});}
我需要更多测试来确定兼容性,但它现在可以工作!
UPDATE: Solution found! Scroll down for my accepted answer!
I want to animate multiple elements of one image and link the animation to ViewPagers position (so multiple elements are morphing or flying in/out depending on the current page being dragged).
So, is there a way to precisely control the current frame of the animation? For example let's assume i have this set:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="800"
android:propertyName="scaleY"
android:valueFrom="0"
android:valueTo="1" />
<objectAnimator
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="800"
android:propertyName="scaleX"
android:valueFrom="0"
android:valueTo="1" />
<objectAnimator
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="800"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360" />
</set>
Animated vector file:
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/pre_signup_1" >
<target
android:name="plus_button"
android:animation="@anim/pre_signup_1_plus_container" />
<target
android:name="plus"
android:animation="@anim/pre_signup_1_plus_sign" />
</animated-vector>
Java code to run the animation:
ImageView mImage1 = (ImageView) findViewById(R.id.image_1);
AnimatedVectorDrawableCompat animated = (AnimatedVectorDrawableCompat) mImage1.getDrawable();
animated.start();
Is there a way to control the animation like setCurrentDuration(400)
which will presumably set the current state of the animation to it's half? Maybe there is a way to split that vector drawable into layers and animate them programmatically? Thanks in advance!
Looks like it is possible to access paths and groups inside VectorDrawableCompat
and animate/morph them however you want!
After a some research I ended up duplicating the following classes from the android.support.graphics.drawable
package: AndroidResources
, PathParser
, TypedArrayUtils
, VectorDrawableCommon
and VectorDrawableCompat
.
Next we need to make the following method and classes public inside of the VectorDrawableCompat
class: getTargetByName
, VGroup
and VFullPath
.
Next in the VectorDrawableCompat
class remove the block that checks for Android version (Build.VERSION.SDK_INT >= 23
). Don't know why, but if you don't do it, the animating won't work on android API 23 and up (need more research).
I may have missed a couple of private methods, but it's just a matter of making them public if you run into problems.
So, now we have access to the layers of our VectorDrawable
! Here is a small example of scaling a vector group depending on the ViewPager
's position:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="276dp"
android:height="359dp"
android:viewportWidth="276"
android:viewportHeight="359">
<group
android:pivotX="205.5"
android:pivotY="214.5"
android:name="my_group">
<path
android:strokeColor="#4D394B"
android:strokeWidth="7"
android:strokeLineJoin="bevel"
android:fillColor="#1ED761"
android:pathData="M206.5,180 C186.9,180,171,195.9,171,215.5 S186.9,251,206.5,251
C226.1,251,242,235.1,242,215.5 S226.1,180,206.5,180 Z" />
<path
android:fillColor="#4D394B"
android:pathData="M210,211 L210,190 L202,190 L202,211 L181,211 L181,219 L202,219 L202,241 L210,241
L210,219 L232,219 L232,211 Z" />
</group>
</vector>
And this is the code used to animate the group:
ImageView myImageView;
VectorDrawableCompat.VGroup myVectorGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
myImageView = (ImageView) findViewById(R.id.image_1);
VectorDrawableCompat vectorDrawable = VectorDrawableCompat.create(getResources(), R.drawable.my_vector_drawable, null);
vectorDrawable.setAllowCaching(false); // Important to allow image updates
myVectorGroup = (VectorDrawableCompat.VGroup) vectorDrawable.getTargetByName("my_group");
myImageView.setImageDrawable(vectorDrawable);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(myVectorGroup != null && position < 1) {
myVectorGroup.setScaleX(1f - positionOffset);
myVectorGroup.setScaleY(1f - positionOffset);
myImageView.invalidate();
}
}
});
}
I need some more testing to determine compatibility, but it works for now!
这篇关于精确控制 Android 的 VectorDrawable 动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:精确控制 Android 的 VectorDrawable 动画
基础教程推荐
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01