动画一遍一遍又一遍,忘了又看,看了又忘,尤其是碎片化严重,决定整理下动画的复习流程,也方便后期自己复习,动画的学习形成体系也是在启舰大佬的自定义《Android自定义控件开发入门与实战》中形成的。现在借助大佬优快云,整理下动画的复习流程。
自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法https://blog.youkuaiyun.com/harvic880925/article/details/39996643
自定义控件三部曲之动画篇(二)——Interpolator插值器
https://blog.youkuaiyun.com/harvic880925/article/details/40049763
自定义控件三部曲之动画篇(三)—— 代码生成alpha、scale、translate、rotate、set及插值器动画
https://blog.youkuaiyun.com/harvic880925/article/details/40117115
自定义控件三部曲之动画篇(四)——ValueAnimator基本使用
https://blog.youkuaiyun.com/harvic880925/article/details/50525521
自定义控件三部曲之动画篇(五)——ValueAnimator高级进阶(一)
https://blog.youkuaiyun.com/harvic880925/article/details/50546884
自定义控件三部曲之动画篇(六)——ValueAnimator高级进阶(二)
https://blog.youkuaiyun.com/harvic880925/article/details/50549385
自定义控件三部曲之动画篇(七)——ObjectAnimator基本使用
https://blog.youkuaiyun.com/harvic880925/article/details/50598322
自定义控件三部曲之动画篇(八)——PropertyValuesHolder与Keyframe
https://blog.youkuaiyun.com/harvic880925/article/details/50752838
自定义控件三部曲之动画篇(九)——联合动画的代码实现
https://blog.youkuaiyun.com/harvic880925/article/details/50759059
自定义控件三部曲之动画篇(十)——联合动画的XML实现与使用示例
https://blog.youkuaiyun.com/harvic880925/article/details/50763286
自定义控件三部曲之动画篇(十一)——layoutAnimation与gridLayoutAnimation
https://blog.youkuaiyun.com/harvic880925/article/details/50785786
自定义控件三部曲之动画篇(十二)——animateLayoutChanges与LayoutTransition
https://blog.youkuaiyun.com/harvic880925/article/details/50985596
自定义控件三部曲之动画篇(十三)——实现ListView Item进入动画
https://blog.youkuaiyun.com/harvic880925/article/details/50988685
举个栗子
现在举一个简单的栗子,要实现一个让一个动画,先看下效果吧
箭头在布局中的位置是在正中间的,然后要实现这样的动画,并且循环播放。
第一阶段:200ms内动画可见度从0到1,并同时从原位置左边150像素的位置移动到目标位置;
第二阶段:600ms内保持不动;
第三阶段:200ms内动画可见度从1到0,同时从原位置到右边150像素。
实现思路
这也是我项目中需要的需求的简化版,其中每个阶段的差值器就设置了,动效部门的同事已经将差值器的值给出,主要是如何用代码实现整个动画过程。
第一种思路就是使用AnimatorSet实现,将三个阶段的动画分别写出来,然后顺序播放,但是又有一个问题,顺序播放的话,AnimatorSet没有循环的api,要是对每个动画都实现无线循环并且顺序播放,那么第一阶段的动画就循环的没有结束,第二阶段和第三阶段的动画根本没机会执行,但是我们可以监听AnimatorSet,监听动画结束之后,我们再重新让动画重新开始,但是这种方法不太优雅,这里就不写代码了,也比较简单。
第二种思路就是KeyFrame(关键帧),我们只需要给出动画切换点的几个关键帧,中间的过渡过程就让系统去实现吧,并且关键帧还支持设置差值器,用到这种场景简直不能再合适了。动画一共3个阶段,第一个阶段就是0到200ms,对应KeyFrame的第一个形参分别是0和0.2,这就有两个KeyFrame了;第二阶段是200ms到800ms,200ms我们已经定义可关键帧,800ms需要定义一个,对应KeyFrame的第一个形参分别是0.8,;第三阶段是800ms到1000ms,我们只需要定义1000ms处,对应KeyFrame的第一个形参分别是1000,如果有差值器我们还需要对每一阶段结束的那个关键帧设置差值器。就这样将这么复杂的动画通过KeyFrame和PropertyValuesHolder整合成一个动画,代码简单,直接上:
public class MainActivity extends AppCompatActivity {
private ImageView mIvRight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIvRight = findViewById(R.id.iv_right);
doAnimator();
}
private void doAnimator() {
Keyframe alpha1 = Keyframe.ofFloat(0f, 0f);
Keyframe alpha2 = Keyframe.ofFloat(0.2f, 1f);
Keyframe alpha3 = Keyframe.ofFloat(0.8f, 1f);
Keyframe alpha4 = Keyframe.ofFloat(1.0f, 0f);
Keyframe translationX1 = Keyframe.ofFloat(0.0f, -150f);
Keyframe translationX2 = Keyframe.ofFloat(0.2f, 0);
Keyframe translationX3 = Keyframe.ofFloat(0.8f, 0f);
Keyframe translationX4 = Keyframe.ofFloat(1.0f, 150f);
PropertyValuesHolder alphaValueHolder = PropertyValuesHolder.ofKeyframe("alpha", alpha1, alpha2, alpha3, alpha4);
PropertyValuesHolder translationXValueHolder = PropertyValuesHolder.ofKeyframe("translationX", translationX1, translationX2, translationX3, translationX4);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mIvRight, alphaValueHolder, translationXValueHolder);
animator.setDuration(1000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.start();
}
}