Android属性动画

动画效果在App开发中是不可或缺的重要内容,我们首选用3.0之后的属性动画来实现动画效果.

概念

顾名思义,属性动画就是通过改变View某些属性值而产生动画效果.通过设置好的目标值及动画时间等参数,系统会帮我们计算好某个时间对应的属性值,甚至在ViewPropertyAnimatorObjectAnimator中会直接帮我们更新计算后的属性值.

系统为我们提供了三种使用属性动画的API,分别是ViewPropertyAnimator,ObjectAnimator,ValueAnimator,从使用复杂度来说一种比一种复杂,但也更灵活.

ViewPropertyAnimator

ViewPropertyAnimator的使用是最简单的,通过view自带的animate()来获取一个ViewPropertyAnimator对象来进行动画操作,代码如下:

    view.animate()
        .alpha(1)   //透明度
        .scaleX(1)  //x轴缩放比例
        .scaleY(1)  //y轴缩放比例
        .translationX(600)  //x轴平移距离
        .translationY(600)  //y轴屏蔽距离
        .rotation(360);     //旋转角度

简单吧,获取到ViewPropertyAnimator对象后只要一行代码就可以开启相应的动画效果,当然也可以设置动画持续时间setDuration(),设置监听,通过withStartAction(),withStartAction()方法可以为动画在开始前和结束后设置对应任务,这两个with方法与监听中回调的onAnimationStart() / onAnimationEnd()有两点不同:

1. withStartAction() / withEndAction() 是一次性的,在动画执行结束后就自动弃掉了,就算之后再重用  ViewPropertyAnimator 来做别的动画,用它们设置的回调也不会再被调用。而 set/addListener() 所设置的 AnimatorListener 是持续有效的,当动画重复执行时,回调总会被调用.
2. withEndAction() 设置的回调只有在动画正常结束时才会被调用,而在动画被取消时不会被执行。这点和 AnimatorListener.onAnimationEnd() 的行为是不一致的.

ViewPropertyAnimator的使用虽然简单方便,但却只能使用几种系统提供好的方法,针对一些特殊或是复杂动画则无能为力,这时我们就可以了解下ObjectAnimator;

ObjectAnimator

ObjectAnimator通过一系列ofXXX()方法来创建实例,xxx代表的就是在动画期间生成的值类型,要与第二个参数传入的字段类型相对应,代码如下:

//参数1表示动画要作用的view对象

//参数2表示要赋值的字段名称,但这里并不会直接修改对应变量值,而是通过set方法来更新,所以这里说是字段名,其实是对应的setXXX方法名,但一般来说XXX字段的set方法都是setXXX.注意要在对应set方法中调用invalidate(),以便在属性值发生变化后重绘.

//参数3是一组可变参数,表示属性值的变化过程
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "progress", 0,65);
animator.start();

以上就是ObjectAnimator的基本使用,一定要注意参数二的概念及在对应set方法中调用invalidate(),再来看看它的一些功能.
1. 使用 PropertyValuesHolder 来对多个属性同时做动画;
2. 使用 AnimatorSet 来同时管理调配多个动画;
3. PropertyValuesHolder 的进阶使用:使用 PropertyValuesHolder.ofKeyframe() 来把一个属性拆分成多段,执行更加精细的属性动画。

PropertyValuesHolder 同一个动画中改变多个属性

我们可能经常需要在一个动画中改变多个属性,这在ViewPropertyAnimator是很方便操作的,但ObjectAnimator中稍有不同,他不支持直接设置多个属性,但提供了PropertyValuesHolder来实现这种操作:

PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("scaleX", 1);  
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleY", 1);  
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("alpha", 1);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, holder1, holder2, holder3)  
animator.start();  
AnimatorSet 多个动画配合执行

有的时候,我们不止需要在一个动画中改变多个属性,还会需要多个动画配合工作,比如,在内容的大小从 0 放大到 100% 大小开始移动。这种情况使用 PropertyValuesHolder 是不行的,因为这些属性如果放在同一个动画中,需要共享动画的开始时间、结束时间、Interpolator 等等一系列的设定,这样就不能有先后次序地执行动画了。这时候就需要使用AnimatorSet了:

        ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "alpha", 0, 1);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "translationX", -200, 200);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "rotation", 0, 1080);
        animator3.setDuration(1000);

        AnimatorSet animatorSet = new AnimatorSet();
        // 用 AnimatorSet 的方法来让三个动画协作执行
        // 要求 1: animator1 先执行,animator2 在 animator1 完成后立即开始
        animatorSet.playSequentially(animator1,animator2);
        // 要求 2: animator2 和 animator3 同时开始
        animatorSet.playTogether(animator2, animator3);

        animatorSet.start();
  • playSequentially()可以让传入的动画按顺序播放;

  • playTogether()可以让传入的动画同时播放;

  • 还可以使用 AnimatorSet.play(animatorA).with/before/after(animatorB)的方式来精确配置各个 Animator 之间的关系

    animatorSet.play(animator1).with(animator2);    //同时
    animatorSet.play(animator1).before(animator2);  //之前
    animatorSet.play(animator1).after(animator2);   //之后
PropertyValuesHolders.ofKeyframe() 把同一个属性拆分

除了合并多个属性和调配多个动画,你还可以在 PropertyValuesHolder 的基础上更进一步,通过设置 Keyframe (关键帧),把同一个动画属性拆分成多个阶段。例如,你可以让一个进度增加到 100% 后再「反弹」回来。

// 在 0% 处开始
Keyframe keyframe1 = Keyframe.ofFloat(0, 0);  
// 时间经过 50% 的时候,动画完成度 100%
Keyframe keyframe2 = Keyframe.ofFloat(0.5f, 100);  
// 时间见过 100% 的时候,动画完成度倒退到 80%,即反弹 20%
Keyframe keyframe3 = Keyframe.ofFloat(1, 80);  
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("progress", keyframe1, keyframe2, keyframe3);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, holder);  
animator.start();  

ValueAnimator

ValueAnimator是一个值的产生器,它并不直接作用于某个view,只是计算出动画过程中需要的属性值,来由我们灵活的使用:

ValueAnimator animator = ValueAnimator.ofInt(0, 100);
animator.setDuration(300);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int animatedValue = (int) animation.getAnimatedValue();
        view.setTranslationX(animatedValue);
    }
});
animator.start();

ValueAnimator的优点是更灵活,不像ViewPropertyAnimator只有固定几个方法,也不想ObjectAnimator必须依赖字段的set方法,ValueAnimator只生产动画过程中的属性值,其它都交给我们自己去实现.

参考

HenCoder Android 自定义 View 1-6:属性动画 Property Animation(上手篇)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值