Android动画效果之Property Animation进阶(属性动画)
来源:互联网 发布:东京 蓝带 知乎 编辑:程序博客网 时间:2024/06/06 01:19
前言:
前面初步认识了Android的Property Animation(属性动画)Android动画效果之初识Property Animation(属性动画)(三),并且利用属性动画简单了补间动画能够实现的动画效果,今天重点学习下Property Animation基本原理及高级使用。本章先通过余额宝的数字动画小例子来学习属性动画基本原理。具体效果如下:
ValueAnimator(差值动画)
上篇文章一直使用的ObjectAnimator来实现属性动画,单纯从字面上理解的话ObjectAnimator作用于某个实际的对象,而ValueAnimator是ObjectAnimator的父类,它继承自抽象类Animator,它作用于一个值,将其由一个值变化为另外一个值,然后根据值的变化,按照一定的规则,动态修改View的属性,比如View的位置、透明度、旋转角度、大小等,即可完成了动画的效果。直接看下上面的数字动画是怎么实现的?
ValueAnimator valueAnimator =ValueAnimator.ofFloat( 0f, 126512.36f);valueAnimator.setDuration(2000);valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float money= (float) animation.getAnimatedValue(); mTextView.setText(String.format("%.2f", money)); }});valueAnimator.start();
这里通过ofFloat()方法构造一个ValueAnimator实例,除此之外还提供了其他函数ofInt()、ofObject()、ofPropertyValuesHolder()函数,api 21之后又提供了ofArgb(),每个函数都是可以传入多个改变值。
Interpolator(插值器)
Interpolator插值器用于控制动画的变化速率,也可以简单的理解成用于控制动画的快慢,插值器目前都只是对动画执行过程的时间进行修饰,并没有对轨迹进行修饰。系统提供的插值器有以下几种:
插值器名字解说对应的xmlAccelerateInterpolator 加速,开始时慢中间加速 @android:anim/accelerate_interpolatorDecelerateInterpolator减速,开始时快然后减速@android:anim/decelerate_interpolatorAccelerateDecelerateInterolator 先加速后减速,开始结束时慢,中间加速 @android:anim/accelerate_decelerate_interpolatorAnticipateInterpolator反向 ,先向相反方向改变一段再加速播放 @android:anim/anticipate_interpolatorAnticipateOvershootInterpolator反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值@android:anim/anticipate_overshoot_interpolatorBounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100@android:anim/bounce_interpolatorCycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2* mCycles* Math.PI* input)@android:anim/cycle_interpolatorLinearInterpolator 线性,线性均匀改变@android:anim/linear_interpolatorOvershootInterpolator超越,最后超出目的值然后缓慢改变到目的值@android:anim/overshoot_interpolator通过上面的名字大家是不是很眼熟,是的和补间动画的插值器是一致的。Android的动画插值器采用策略设计模式,都是实现了Interpolator这个接口,而Interpolator又是继承自一个叫做TimeInterpolator的接口(从3.0开始,增加了TimeInterpolator这个接口,并把原先的Interpolator接口的抽象方法移到了其中,3.0后的Interpolator接口也就什么也没做,只是对父类改了个名字,达到向下兼容)。
package android.animation;public interface TimeInterpolator { float getInterpolation(float input);}
在Interpolator的实现类里面,都实现了一个float getInterpolator(float input)的方法,传入参数是正常执行动画的时间点,返回值是用户真正想要它执行的时间点。上面的数字动画使用了匀速插值器LinearInterpolator其代码实现如下:
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public LinearInterpolator() { } public LinearInterpolator(Context context, AttributeSet attrs) { } public float getInterpolation(float input) { return input; } /** @hide */ @Override public long createNativeInterpolator() { return NativeInterpolatorFactoryHelper.createLinearInterpolator(); }}
可以看出float getInterpolator(float input)返回的值就是当前要执行的时间点实现匀速执行动画。
如何自定义一个插值器?举例:我们实现一个先减速后加速插值器,代码如下
public class DecelerateAccelerateInterpolator implements Interpolator { @Override public float getInterpolation(float input) { float result; if (input <= 0.5f) { result = (float) (Math.sin(Math.PI * input)) / 2.0f; } else { result = (float) (2 - Math.sin(Math.PI * input)) / 2.0f; } return result; }}
TypeEvaluator(估值器)
TypeEvaluator用于根据当前属性改变的百分比来计算改变后的属性值,系统提供了如下几种估值器
IntEvaluator 针对整型属性
IntArrayEvaluator 针对整型属性集合
FloatEvaluator 针对浮点型属性
FloatArrayEvaluator 针对浮点型属性集合
ArgbEvaluator 针对Color属性
RectEvaluator 针对Rect属性
PointFEvaluator 针对PointF属性
TypeEvaluator设计也是采用策略设计模式,都实现TypeEvaluator接口,源代码如下:
package android.animation;public interface TypeEvaluator<T> { public T evaluate(float fraction, T startValue, T endValue);}
接口提供了evaluate(float fraction, T startValue, T endValue);动画在运行过程中Interpolator自动计算出动画运行的百分比fraction,然后TypeEvaluator根据fraction计算出当前动画的属性值。以FloatEvaluator 代码为例:
public class FloatEvaluator implements TypeEvaluator<Number> { public Float evaluate(float fraction, Number startValue, Number endValue) { float startFloat = startValue.floatValue(); return startFloat + fraction * (endValue.floatValue() - startFloat); }}
如何自定义TypeEvaLuator?比如我们要实现一个钱的增加,字体颜色越红的动画,我们现在都知道可以使用ofArgb(),但是ofArgb()需要api 21以上才能使用,所以需要我们自定义一个ArgbEvaLuator,这里为了演示自定义TypeEvaluator直接把api 21中提供的ArgbEvaluator源代码拿来使用,如下:
public class TextArgbEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { int startInt = (Integer) startValue; int startA = (startInt >> 24) & 0xff; int startR = (startInt >> 16) & 0xff; int startG = (startInt >> 8) & 0xff; int startB = startInt & 0xff; int endInt = (Integer) endValue; int endA = (endInt >> 24) & 0xff; int endR = (endInt >> 16) & 0xff; int endG = (endInt >> 8) & 0xff; int endB = endInt & 0xff; return (int) ((startA + (int) (fraction * (endA - startA))) << 24) | (int) ((startR + (int) (fraction * (endR - startR))) << 16) | (int) ((startG + (int) (fraction * (endG - startG))) << 8) | (int) ((startB + (int) (fraction * (endB - startB)))); }}
调用方式:
AnimatorSet animatorSet = new AnimatorSet(); ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 126512.36f); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float money = (float) animation.getAnimatedValue(); Log.e("Interpolator", "money---->" + money); mTextView.setText(String.format("%.2f", money)); } }); int startColor = Color.parseColor("#FCA3AB"); int endColor = Color.parseColor("#FB0435"); ValueAnimator colorAnimator = ValueAnimator.ofObject(new TextArgbEvaluator(),startColor, endColor); colorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int color = (int) animation.getAnimatedValue(); Log.e("Interpolator", "color---->" + color); mTextView.setTextColor(color); } }); animatorSet.playTogether(valueAnimator,colorAnimator); animatorSet.setDuration(5000); animatorSet.setInterpolator(new LinearInterpolator()); animatorSet.start();
运行效果:
ObjectAnimator
上篇我们简单了学习了ObjectAnimator动画,并且通过ObjectAnimator实现了几种简单的动画效果,ObjectAnimator继承自ValueAnimator,所以主体方法还是ValueAnimator里实现的。先来回顾一下上篇的一个旋转动画例子。
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f); objectAnimator.setDuration(500); objectAnimator.setRepeatCount(1); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.start();
这个例子很简单,针对view的属性rotation进行持续时间为500ms的0到360的角度变换。属性名字rotation在View中有对应setRotation(),否则没有任何效果,而且参数类型必须为float型,否则没有任何效果。view常见可操作的参数有:x/y;scaleX/scaleY;rotationX/ rotationY;transitionX/ transitionY等等。现在问题来了,我们本篇例子是为TextView 赋值一个float型的值,我们查看TextView的函数并不找不到setText(float f),这时该怎么处理呢?如何为不具有get/set方法的属性提供修改方法呢?莫着急!谷歌为此提供了两种方法,第一种就是使用ValueAnimator来实现,就是上面所说的方式,另外一种方式通过自己写一个包装类,来为该属性提供get/set方法。
public class MoneyTextView extends TextView { public MoneyTextView(Context context, AttributeSet attrs) { super(context, attrs); } public void setText(float money) { setText(String.format("%.2f", money)); }}
然后就可以通过ObjectAnimator实现上面的数字动画效果了。
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mTextView, "text", 0f, 126512.36f); objectAnimator.setDuration(2000); objectAnimator.setInterpolator(new LinearInterpolator()); objectAnimator.start();
其他有关ObjectAnimator的使用方式请参考上篇文章Android动画效果之初识Property Animation(属性动画)(三)。
总结:
本篇主要简单学习了属性动画的基本原理,属性动画使用了比较常见的策略设计模式,感兴趣的话可以看下这篇文章Java设计模式之策略模式(Strategy),下篇文章将借助自定义ViewGroup学习一下布局动画。
- Android动画效果之Property Animation进阶(属性动画)
- Android动画效果之Property Animation进阶(属性动画)
- android动画效果之Property Animation进阶(属性动画)
- Android动画效果之Property Animation进阶(属性动画)(四)
- Android动画效果之初识Property Animation(属性动画)
- Android动画效果之初识Property Animation(属性动画)
- Android动画效果之- Property Animation(属性动画)
- Android动画效果之初识Property Animation(属性动画)
- Android动画之属性动画(Property Animation)(一)
- Android动画之属性动画(Property Animation)(二)
- Android动画之属性动画(Property Animation)(三)
- Android动画(三)之属性动画(Property Animation)
- Android 动画详解之属性动画(Property Animation)(下)
- Android动画之Property Animation(属性动画)
- Android学习之 属性动画<Property Animation>
- Android基础篇之属性动画(Property Animation)
- Android基础篇之属性动画(Property Animation)
- Android属性动画---Property Animation(一)
- 使用Log4j将程序日志实时写入Kafka
- SringBuffer与String的区别
- 【tyvj1061】Mobile Service(dp)
- 正则表达式的应用
- 如何解决coursera视频无法播放
- Android动画效果之Property Animation进阶(属性动画)
- robot 自动化(一) 安装使用sshlibray
- Android7.0 ShapeDrawable背景样式圆角
- 通过使用第三方SDK来实现应用的分享,第三方登陆,数据信息统计等功能(ShareSDK)。
- Browsersync浏览器同步测试工具-打开文件
- C语言(24)蛇形填数
- 三种常见字符编码简介:ASCII、Unicode和UTF-8
- Java的Executor框架和线程池实现原理
- 安装loadrunner,缺少VC2005_sp1_with_atl的错