再复杂的动画,都是简单动画的结合
I. Tween Animation(补间动画)
形式 | 备注 |
---|---|
alpha | 渐变透明度 |
scale | 渐变尺寸 |
translate | 画面位置移动 |
rotate | 画面旋转 |
实现方式
Animation
配合AnimationUtils
,结合xml中set
II. Frame Animation(关键帧动画)
顺序播放关键帧
实现方式
AnimationDrawable
结合xml中定义animation-list
标签
AnimationDrawable
本身无法监听动画状态
III. 对象属性动画
Andorid 3.0加入(如果3.0以下想用使用,可以参考开源动画库: http://nineoldandroids.com/)
基本概念: 可以对对象属性进行动画,不仅仅是View
动画的默认帧率是一帧10ms(100帧/s(Android正常绘制60帧/s))
1. TimeInterpolator(时间插值器)
根据时间流逝的百分比来计算出当前属性值改变的百分比
系统默认提供的
LinearInterpolator
: 线性插值器,匀速动画AccelerateDecelerateInterpolator
: 加速减速插值器,动画两头慢中间快DecelerateInterpolator
: 减速插值器,动画越来越慢AccelerateInterpolator
: 加速插值器,动画越来越快
…
2. TypeEvaluator(类型估值算法)
根据当前属性改变的百分比来计算改变后的属性值
系统默认提供的
IntEvaluator
: 针对整型属性FloatEvaluator
: 针对浮点型属性ArgbEvaluator
: 针对Color属性
…
TypeEvaluator与TimeInterpolator是实现非匀速动画的神器。
实现方式
TimeInterpolator与TypeEvaluator两者是配合使用的,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class LinearInterpolator implements Interpolator { ... public float getInterpolation(float input) { // 返回时间流逝的百分比 input = (当前时间 - 开始时间)/ 总时间 return input; // 匀速 //return input * input; //加速 } } public class IntEvaluator implements TypeEvaluator<Integer> { public Integer evaluate(float fraction, Integer startValue, Integer endValue) { // 返回需要变化的整型 int startInt = startValue; // fraction: LinearInterpolator返回的流逝百分比 return (int)(startInt + fraction * (endValue - startInt)); } } |
3. ObjectAnimator、ValueAnimator、AnimatorSet
都可以直接在xml中定义 / 直接代码中实现,结合TimeInterpolator与TypeEvaluator,几乎可以实现所有想要的动画
例子:
为了理解,直接看几个例子
ps: 以下例子来自: Android动画进阶—使用开源动画库nineoldandroids与Android属性动画深入分析:让你成为动画牛人
第二个参数PropertyName
PropertyName: 如第一个例子的”translationY”
我们定义第一个例子中的myObject为target
如果Animator中已经提供初始值,就只需要target包含Property的set方法(如第一个例子中myObject需要包含
setTranslationY(float)
)如果Animator中未提供初始值,除了需要set方法,还需要包含Property的get方法(如地i一个例子中myObject需要包含
getTranslationY():float
)满足以上两条,就可以定义为Property
ps: 如果View/某对象没有满足上面的条件,如果可以,未尝不可自己封装一层实现。
1 2 | // 默认时间内,移动其高度的距离 ObjectAnimator.ofFloat(myObject, "translationY", -myObject.getHeight()).start(); |
1 2 3 4 5 6 7 8 9 | // 不断循环3s内背景颜色从红色渐变到蓝色再到红色 ValueAnimator colorAnim = ObjectAnimator.ofInt( this, "backgroundColor", /*Red*/0xFFFF8080,/*Blue*/0xFF8080FF); colorAnim.setDuration(3000); colorAnim.setEvaluator(new ArgbEvaluator()); colorAnim.setRepeatCount(ValueAnimator.INFINITE); colorAnim.setRepeatMode(ValueAnimator.REVERSE); colorAnim.start(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 5s内同时对View旋转、平移、缩放、透明都进行了改变 AnimatorSet set = new AnimatorSet(); set.playTogether( ObjectAnimator.ofFloat(myView, "rotationX", 0, 360), ObjectAnimator.ofFloat(myView, "rotationY", 0, 180), ObjectAnimator.ofFloat(myView, "rotation", 0, -90), ObjectAnimator.ofFloat(myView, "translationX", 0, 90), ObjectAnimator.ofFloat(myView, "translationY", 0, 90), ObjectAnimator.ofFloat(myView, "scaleX", 1, 1.5f), ObjectAnimator.ofFloat(myView, "scaleY", 1, 0.5f), ObjectAnimator.ofFloat(myView, "alpha", 1, 0.25f, 1) ); set.setDuration(5 * 1000).start(); |
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 | // ValueAnimator的使用 // 5s内匀速修改target的宽度 private void performAnimate(final View target, final int start, final int end) { ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100); valueAnimator.addUpdateListener(new AnimatorUpdateListener() { //持有一个IntEvaluator对象,方便下面估值的时候使用 private IntEvaluator mEvaluator = new IntEvaluator(); @Override public void onAnimationUpdate(ValueAnimator animator) { //获得当前动画的进度值,整型,1-100之间 int currentValue = (Integer)animator.getAnimatedValue(); Log.d(TAG, "current value: " + currentValue); //计算当前进度占整个动画过程的比例,浮点型,0-1之间 float fraction = currentValue / 100f; //直接调用整型估值器通过比例计算出宽度,然后再设给Button target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end); target.requestLayout(); } }); valueAnimator.setDuration(5000).start(); } |
共同学习,写下你的评论
评论加载中...
作者其他优质文章