博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android属性动画
阅读量:7036 次
发布时间:2019-06-28

本文共 4555 字,大约阅读时间需要 15 分钟。

动画效果在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只生产动画过程中的属性值,其它都交给我们自己去实现.

参考

转载地址:http://ceyal.baihongyu.com/

你可能感兴趣的文章
根据实践经验,讲述些学习Java web能少走的弯路,内容摘自java web轻量级开发面试教程...
查看>>
解读邮箱正则表达式:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
查看>>
C#线程篇---Task(任务)和线程池不得不说的秘密(5)
查看>>
Linux系列教程(十九)——Linux文件系统管理之手工分区
查看>>
Java开发中的23种设计模式详解(转)
查看>>
Math.Celing、Math.Floor、Math.DivRem与Math.BigMul
查看>>
unknown filesystem type ‘iso9660’类型问题--Ubuntu
查看>>
如何恢复U盘里的删除文件?
查看>>
sentry docker-compsoe 安装以及简单使用
查看>>
制作Kinect体感控制小车教程 <一>
查看>>
HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor
查看>>
PL/SQL学习笔记之游标
查看>>
【linux c】setsockopt 详解
查看>>
使用Httpclient 完美解决服务端跨域问题
查看>>
对数据库进行增删改查操作
查看>>
JS中replace替换全部的正确应用
查看>>
python中dict操作集合
查看>>
laravel中的Auth认证:
查看>>
同一客户端多个git账号的配置
查看>>
SpringBoot application.properties (application.yml)优先级从高到低
查看>>