Android属性动画(三)——TypeEvaluator(估值器)和Interpolator(插值器)
来源:互联网 发布:4399淘宝旗舰店 编辑:程序博客网 时间:2024/05/22 07:44
前几篇文章我们介绍了ObjectAnimator和ValueAnimator的基本用法。
TypeEvaluator(估值器)
细心的朋友会发现我们有一个东西没有用到。
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values)
当我们ValueAnimator.ofObject()函数来做动画效果的时候就会用到估值器了,估值器说白了就是用来确定在动画过程中每时每刻动画的具体值得换句话说就是确定ValueAnimator.getAnimatedValue()返回的具体对象类型。
系统内置的估值器有:
- IntEvaluator Int类型估值器,返回int类型的属性改变
- FloatEvaluator Float类型估值器,返回Float类型属性改变
- ArgbEvaluator 颜色类型估值器
TypeEvaluator源码:
package android.animation;public interface TypeEvaluator<T> { public T evaluate(float fraction, T startValue, T endValue);}
- 第一个参数表示动画完成度。
- 第二个和第三个参数分别是初始值和结束值。
ValueAnimator.ofFloat()方法就是实现了初始值与结束值之间的平滑过度,它内置了一个FloatEvaluator。
package android.animation;/** * This evaluator can be used to perform type interpolation between <code>float</code> values. */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); }}
ok,我们自己实现一个估值器实现一个动画效果。先看看效果。
Point对象存放CircleView的属性
public class Point { private float mRadius; public float x; public float y; public Point(float x, float y, float mRadius) { this.x = x; this.y = y; this.mRadius = mRadius; } public Point() { } public float getRadius() { return mRadius; } public void setRadius(float mRadius) { this.mRadius = mRadius; } public float getX() { return x; } public void setX(float x) { this.x = x; } public float getY() { return y; } public void setY(float y) { this.y = y; }}
估值器,这里用了三角函数来计算x,y坐标
public class CircleTypeEvaluator implements TypeEvaluator { private float radius;//旋转的半径 public CircleTypeEvaluator(float radius) { this.radius = radius; } @Override public Object evaluate(float fraction, Object startValue, Object endValue) { Point point = new Point(); Point startPoint = (Point) startValue; //旋转的角度 float angle = fraction * 360; float longY = (float) ((radius *(1- Math.cos(Math.toRadians(angle)))));//计算y坐标 point.setY(startPoint.getY() + longY); float longX = (float) (radius - radius * Math.sin(Math.toRadians(angle)));//计算x坐标 point.setX(startPoint.getX() + longX-radius); return point; }}
CircleView
public class CircleView extends View { private Paint paint; private Point point; public CircleView(Context context) { super(context); init(); } public CircleView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ paint=new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(getResources().getColor(android.R.color.holo_blue_light)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (point==null){ point = new Point(getWidth()/2,getHeight()/2,100); canvas.drawCircle(point.x,point.y,point.getRadius(),paint); }else{ canvas.drawCircle(point.getX(),point.getY(),point.getRadius(),paint); } } public void setViewPoint(Point result){ point.setX(result.getX()); point.setY(result.getY()); invalidate(); }}
ok,使用的时候,这里球的半径是固定的100
circleView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Point start = new Point(circleView.getWidth()/2,circleView.getHeight()/2,100); ValueAnimator animator = ValueAnimator.ofObject(new CircleTypeEvaluator(200),start,start); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Point result = (Point) animation.getAnimatedValue(); circleView.setViewPoint(result); } }); animator.setDuration(2000); animator.setRepeatCount(-1); animator.start(); } });
Interpolator(插值器)
在动画的播放过程中Android中提供插值器来改变动画的播放速率,采用不用的插值器来实现不同的播放效果。
大家有没有发现上面我们讲TypeEvaluator的例子,蓝色的小球运动的速率是由慢到快再变慢,因为系统默认的使用的插值器是AccelerateDecelerateInterpolator默认实现这种效果。
Interpolator接口从Android 1.0版本开始就一直存在,我们讲Tween动画的时候就是用过。属性动画中新增了一个TimeInterpolator接口,Interpolator是继承TimeInterpolator接口的。系统已经有很多可以直接使用的类。
使用方法很简单
animator.setInterpolator(new AccelerateInterpolator());
自定义Interpolator
有时候系统提供的实现类并不能满足我们的需求,所以就需要自定义Interpolator。
所有的插值器都要去实现TimeInterpolator接口,TimeInterpolator接口代码如下。
public interface TimeInterpolator { /** * Maps a value representing the elapsed fraction of an animation to a value that represents * the interpolated fraction. This interpolated value is then multiplied by the change in * value of an animation to derive the animated value at the current elapsed animation time. * * @param input A value between 0 and 1.0 indicating our current point * in the animation where 0 represents the start and 1.0 represents * the end * @return The interpolation value. This value can be more than 1.0 for * interpolators which overshoot their targets, or less than 0 for * interpolators that undershoot their targets. */ float getInterpolation(float input);}
从代码中可以看到这里只需要实现getInterpolation()函数就好了。
TimeInterpolator接口里面getInterpolation函数的参数input就是动画每一次播放过程中的时间比例值,是0-1之间的值,但是返回的值是可以大于1,也是可以小于0的,对于返回值倒是没什么特定的要求。
我们先看看系统的插值器是怎么实现的,AccelerateDecelerateInterpolator :
/** * An interpolator where the rate of change starts and ends slowly but * accelerates through the middle. */@HasNativeInterpolatorpublic class AccelerateDecelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public AccelerateDecelerateInterpolator() { } @SuppressWarnings({"UnusedDeclaration"}) public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) { } public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } /** @hide */ @Override public long createNativeInterpolator() { return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator(); }}
- 构造函数
第一个是无参构造是我们具体JAVA代码中new的时候用到,第二个构造函数是在资源文件里面使用的时候调用的(@android:anim/accelerate_decelerate_interpolator的时候会调用这个构造方法)。 - getInterpolation()方法
AccelerateDecelerateInterpolator插值器的曲线图得到对应的数学表达式(cos((x + 1) * PI) / 2.0) + 0.5,然后数学表达式转换为代码形式,(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f。
我们开始定义自己的Interpolator。
第一步确定我们要实现的插值器的曲线图。
第二步数学表达式,需要一定的数学功底
pow(2, -10 * x) * sin((x - factor / 4) * (2 * PI) / factor) + 1
factor = 0.2 这个我们在构造函数的时候指定
第三步
public class SpringInterpolator implements Interpolator { private static final float DEFAULT_FACTOR = 0.2f; private float mFactor; public SpringInterpolator() { this(DEFAULT_FACTOR); } public SpringInterpolator(float mFactor) { this.mFactor = mFactor; } @Override public float getInterpolation(float input) { // pow(2, -10 * input) * sin((input - factor / 4) * (2 * PI) / factor) + 1 return (float) (Math.pow(2, -10 * input) * Math.sin((input - mFactor / 4.0d) * (2.0d * Math.PI) / mFactor) + 1); }}
animator.setInterpolator(new SpringInterpolator());
看看效果
- Android属性动画(三)——TypeEvaluator(估值器)和Interpolator(插值器)
- Android 动画-Interpolator和TypeEvaluator
- Android动画TimeInterpolator(插值器)和TypeEvaluator(估值器)分析
- Android动画TimeInterpolator(插值器)和TypeEvaluator(估值器)分析
- Android属性动画Interpolator(插值器)
- 安卓属性动画之插值器(TimeInterpolator)和估值器(TypeEvaluator)
- 安卓属性动画之插值器(TimeInterpolator)和估值器(TypeEvaluator)
- 属性动画高级用法之TypeEvaluator和Interpolator
- Android开发 之 属性动画(自定义ValueAnimator的TypeEvaluator)
- android动画之interpolator和typeEvaluator用法详解
- Android动画--Interpolator(插值器)
- Android属性动画--TypeEvaluator
- 浅析 Android 动画:自定义 Interpolator 与 TypeEvaluator
- Android属性动画(下),InterPolator、ViewPropertyAnimator和布局动画的用法
- Android属性动画(二) ValueAnimator的实际应用 & 自定义TypeEvaluator
- android 动画中插值器(Interpolator)属性的分析
- android动画(一)Interpolator
- android动画(一)Interpolator
- HTML5学习_day06(2)--html之相对定位
- 可以自动换行的RadioGroup (默认水平布局)
- HTML学习笔记
- Python dict()追加数据
- ORACLE 查看字符集
- Android属性动画(三)——TypeEvaluator(估值器)和Interpolator(插值器)
- iOS 报错:you don't have permission
- 计算背景图片的灰度值,设置文字的颜色
- VueJs 自定义过滤器使用总结
- bootstrap 的模态框 内部组件无法获取焦点
- pushlet的一般流程
- NVIDIA Jetson TX1(1)
- 判断某个导航控制器当前是否正在显示
- RabbitMQ (二)工作队列