「解决方案」Android Vector动画实现三个小球循环转动的加载动画
公司项目中需要使用到一个三个小球循环转动的加载动画,最初给的是一帧帧的切图做帧动画,后来在android sdk25上面发生了内存泄漏Out Of Memory(OOM),于是就考虑着更换一下实现方式,于是就开始尝试使用Vector矢量动画来实现了。
效果预览
原始Vector
在drawable目录下创建一个名为icon_pull_refresh的xml文件。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="600dp" android:height="200dp" android:viewportWidth="600" android:viewportHeight="200">
<group android:name="left"> <path android:fillColor="#FF00FF" android:pathData="M75 148 a 48 48 0 1 0 -1 0z" /> </group>
<group android:name="middle"> <path android:fillColor="#FF00FF" android:pathData="M300 175 a 75 75 0 1 0 -1 0z" /> </group>
<group android:name="right"> <path android:fillColor="#FF00FF" android:pathData="M525 148 a 48 48 0 1 0 -1 0z" /> </group> </vector>
|
属性动画
左侧小球转动到中间
在animator目录下创建名为animator_pull_refresh_left2middle的xml文件。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator android:duration="1000" android:propertyName="translateX" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="0" android:valueTo="182.8125" android:valueType="floatType"/>
<objectAnimator android:duration="1000" android:propertyName="translateY" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="0" android:valueTo="-56.25" android:valueType="floatType"/>
<objectAnimator android:duration="1000" android:propertyName="scaleX" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="1" android:valueTo="1.5625" android:valueType="floatType"/>
<objectAnimator android:duration="1000" android:propertyName="scaleY" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="1" android:valueTo="1.5625" android:valueType="floatType"/>
</set>
|
中间小球转动到右边
在animator目录下创建名为animator_pull_refresh_middle2right的xml文件。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator android:duration="1000" android:propertyName="translateX" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="0" android:valueTo="333" android:valueType="floatType"/>
<objectAnimator android:duration="1000" android:propertyName="translateY" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="0" android:valueTo="36" android:valueType="floatType"/>
<objectAnimator android:duration="1000" android:propertyName="scaleX" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="1" android:valueTo="0.64" android:valueType="floatType"/>
<objectAnimator android:duration="1000" android:propertyName="scaleY" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="1" android:valueTo="0.64" android:valueType="floatType"/> </set>
|
右侧小球转动到左边
在animator目录下创建名为animator_pull_refresh_right2left的xml文件。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="utf-8"?> <set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:propertyName="translateX" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="0" android:valueTo="-450" android:valueType="floatType"/>
</set>
|
Vector矢量动画实现
在drawble目录下创建名为animation_refresh的xml文件。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="utf-8"?> <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/icon_pull_refresh"> <target android:name="left" android:animation="@animator/animator_pull_refresh_left2middle" /> <target android:name="middle" android:animation="@animator/animator_pull_refresh_middle2right" /> <target android:name="right" android:animation="@animator/animator_pull_refresh_right2left" /> </animated-vector>
|
使用矢量动画
在布局文件中使用矢量动画
1 2 3 4 5
| <androidx.appcompat.widget.AppCompatImageView app:srcCompat="@drawable/animation_refresh" android:layout_width="wrap_content" android:id="@+id/aciv_refresh" android:layout_height="wrap_content" />
|
在代码中执行矢量动画
1
| (acivRefresh.drawable as AnimatedVectorDrawable).start()
|
写在最后
最终Android Vector矢量动画方案实现了三个小球循环转动的加载动画。但是由于实现方案复杂,改动困难最终方案又被pass了。考虑到现在sdk25存量已经比较小了,因此不考虑使用此替代方案。最终把关注点放到了内存泄漏上。