常用的View的成员属性
- translationX、Y 控制View的位置,指的是相对于View容器左上角坐标的偏移
- rotationX、Y 控制相对于轴心旋转
- x、y 控制View在容器中的位置,左上角坐标加上translationX、Y的值。
- alpha 控制View的透明度。
属性动画的实现原理就是修改View的属性值来实现的动画。
所有的属性动画的抽象基类是Animator,属性动画的实现类有7个:
- AnimatorSet 动画集合
- FakeAnimator
- ObjectAnimator 一个对象的一个属性动画
- RenderNodeAnimator
- RevealAnimator
- TimeAnimator 时序监听回调工具
- ValueAnimator 在一个特定的时间里执行一个动画
计算原理
属性动画提供了一些属性
属性 | 含义 |
---|---|
duration | 动画持续时间 |
TimeInterpolation | 定义动画变化速率的接口,所有插值器都必须实现此接口 |
TypeEvaluator | 用于定义属性值计算方法的接口,有 int、float、color 类型,根据属性的起始、结束值和插值一起计算出当前时间的属性值 |
Animation sets | 动画集合,即可以同时对一个对象应用多个动画,这些动画可以同时播放也可以对不同动画设置不同的延迟 |
Frame refreash delay | 多少时间刷新一次,即每隔多少时间计算一次属性值,默认为 10ms,最终刷新时间还受系统进程调度与硬件的影响 |
Repeat Country and behavoir | 重复次数与方式,如播放3次、5次、无限循环,可以让此动画一直重复,或播放完时向反向播放 |
通过以上属性,我们可以定义线性匀速运动动画、非匀速运动动画。
这一点和ios的toValue可以定义一组数据一样,通过插值来控制某一时间点的位置或其他属性的值。
这里理解起来结合iOS的fromValue/toValue就很容易理解了。
ValueAnimator 是动画的执行类,跟踪了当前动画的执行时间和当前时间下的属性值。
ValueAnimator类里封装了一个TimeInterpolator 时间插值器和一个 TypeEvaluator 类型估值,用于设置动画属性的值。
-
为了执行一个动画,你需要创建一个 ValueAnimator,并且指定目标对象属性的开始、结束值和持续时间。
-
在调用 start 后, 整个动画过程中, ValueAnimator 会根据已经完成的动画时间计算得到一个 0 到 1 之间的值,代表该动画的已完成动画百分比。 0 表示 0%,1 表示 100%,譬如上面图一线性匀速动画中总时间 t = 40 ms,t = 10 ms 的时候是 0.25。
-
当 ValueAnimator 计算完已完成百分比后,它会调用当前设置的 TimeInterpolator, 去计算得到一个 interpolated(插值)分数,在计算过程中,已完成百分比会被加入到新的插值计算中。
-
当插值分数计算完成后,ValueAnimator 会根据插值分数调用合适的 TypeEvaluator 去计算运动中的属性值。
总结就是
- 创建一个ValueAnimator
- 调用 start,ValueAnimator计算完成进度progressing
- ValueAnimator.timeInterpolator计算得到一个interpolated
- ValueAnimator根据interpolated调用合适的TypeEvaluator计算运动中的属性值。
XML方式的属性动画
路径是res/animator/文件夹下的xml文件,根标签可以为ValueAnimator<animator>、ObjectAnimator <objectAnimator>、AnimatorSet<set>。
在java中的使用:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
R.animtor.property_animator);
set.setTarget(myObject);
set.start();
Java方式
- ObjectAnimator:
继承自 ValueAnimator,指定要进行动画的对象,以及该对象的一个属性。根据计算得到的新值自动更新属性。
不用像 ValueAnimator 那样自己写动画更新的逻辑,但ObjectAnimator 有一定的限制,比如它需要目标对象的属性提供指定的处理方法(set和get)
特别注意:ObjectAnimator 的动画原理是不停的调用 setXXX 方法更新属性值(触发重绘),所有使用 ObjectAnimator 更新属性时的前提是 Object 必须声明有getXXX和setXXX方法。但是也有特殊情况,譬如作用 Object 不是 View,或者作用的属性没有触发重绘。
- PropertyValuesHolder:
多属性动画同时工作管理类。有时候我们需要同时修改多个属性,那就可以用到此类,具体如下:
PropertyValuesHolder a1 = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);
PropertyValuesHolder a2 = PropertyValuesHolder.ofFloat("translationY", 0, viewWidth);
......
ObjectAnimator.ofPropertyValuesHolder(view, a1, a2, ......).setDuration(1000).start();
如上代码就可以实现同时修改多个属性的动画啦。
- ValueAnimator:
以时间驱动,管理着动画时间的开始、结束属性值,相应时间属性值计算方法等。包含所有计算动画值的核心函数以及每一个 动画时间节点上的信息、一个动画是否重复、是否监听更新事件等,并且还可以设置自定义的计算类型。
特别注意: ValueAnimator 只是动画计算管理驱动,设置了作用目标,但没有设置属性,需要通过 updateListener 里设置属性才会生效。
ValueAnimator animator = ValueAnimator.ofFloat(0, mContentHeight); //定义动画
animator.setTarget(view); //设置作用目标
animator.setDuration(5000).start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation){
float value = (float) animation.getAnimatedValue();
view.setXXX(value); //必须通过这里设置属性值才有效
view.mXXX = value; //不需要setXXX属性方法
}
});
- AnimationSet:
动画集合,提供把多个动画组合成一个组合的机制,并可设置动画的时序关系,如同时播放、顺序播放或延迟播放。具体使用方法比较简单, 如下:
ObjectAnimator a1 = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0f);
ObjectAnimator a2 = ObjectAnimator.ofFloat(view, "translationY", 0f, viewWidth);
......
AnimatorSet animSet = new AnimatorSet();
animSet.setDuration(5000);
animSet.setInterpolator(new LinearInterpolator());
//animSet.playTogether(a1, a2, ...); //两个动画同时执行
animSet.play(a1).after(a2); //先后执行
......//其他组合方式
animSet.start();
- Evaluators :
Evaluators 就是属性动画系统如何去计算一个属性值。它们通过 Animator 提供的动画的起始和结束值去计算一个动画的属性值。
IntEvaluator:整数属性值。
FloatEvaluator:浮点数属性值。
ArgbEvaluator:十六进制color属性值。
TypeEvaluator:用户自定义属性值接口,譬如对象属性值类型不是 int、float、color 类型, 你必须实现这个接口去定义自己的数据类型。
网友评论