属性动画高级用法之TypeEvaluator和Interpolator
来源:互联网 发布:华东师范大学知乎 编辑:程序博客网 时间:2024/06/06 23:57
1、Interpolator 插值器,控制动画的变化速率,就是通常描述的加速度,可以简单理解为变化的快慢,它是一个接口,实现类如下
从上面关系图可以看到,差值器最终实现的接口是TimeInterpolator,它的源码如下
public interface TimeInterpolator { float getInterpolation(float input);}参数input的值介于0和1,显示当前在动画中所经过的动画时间的动画值,0个代表开始和1个代表结。束
1.1、下面是DecelerateInterpolator的源码,看下getInterpolation方法的实现,如果mFactor 等于1.0f就会执行
result = (float)(1.0f - (1.0f - input) * (1.0f - input));上面这行翻译过来就是抛物线函数 1-(1-x)*(1-x) ,它对应的二维坐标图如下。可以看到x的值在[0,1]之间直线与抛物线的切点交于横坐标的角度在变小,而这里的角度可以看做是加速度,因此DecelerateInterpolator做的是减速运动。其他的插值器原理类似,这里就不在描述。
public class DecelerateInterpolator implements Interpolator { public DecelerateInterpolator() { } /** * Constructor * * @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces * an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the * ease-out effect (i.e., it starts even faster and ends evens slower) */ public DecelerateInterpolator(float factor) { mFactor = factor; } public DecelerateInterpolator(Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.DecelerateInterpolator); mFactor = a.getFloat(com.android.internal.R.styleable.DecelerateInterpolator_factor, 1.0f); a.recycle(); } public float getInterpolation(float input) { float result; if (mFactor == 1.0f) { result = (float)(1.0f - (1.0f - input) * (1.0f - input)); } else { result = (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor)); } return result; } private float mFactor = 1.0f;}
1.2、自定义插值器
自定义插值器需要实现接口 Interpolator,代码很简单如下 ,先减速后加速,是一个抛物口朝上抛物线。
<span style="font-size:14px;">public class ParabolaInterpolator implements Interpolator {@Overridepublic float getInterpolation(float input) {return (2 * input - 1) * (2 * input - 1);}}</span>
2、TypeEvaluator估值器
系统自带的估值器有下面几种
下面是小球按照正玄曲线从屏幕左边移动到右边,效果图如下
在这里使用的正玄曲线曲线公式是(float) Math.sin((30 * fraction) - Math.PI/2)+1,翻译成数学公式就是sin(10πx-π/2)+1,取值范围是[0,2]。如果将公式放到自定义的TypeEvaluator里面,配合动画就可以实时返回y和x的坐标值。
正玄曲线图如下:
现在开始进行自定义view的绘制,实现小球移动
2.1 移动
这个比较简单,通过paint和canvas对象结合可以绘制一个小球,通过坐标改变然后刷新界面重新绘制就可以移动。
2.2 设置动画,获取坐标
采用属性动画,因为ValueAnimator对象可以传入一个TypeEvaluator<T>对象,通过上面知道TypeEvaluator可以计算出坐标值。
2.3 移动
可以设置动画监听器addUpdateListener,可以获取到当前坐标,在调用界面刷新。
废话不多说,下面是源码
<span style="font-size:14px;">public class MoveCircle extends View {//小球半径private int radius=30;//画笔private Paint mPaint;//保存小球移动过程中的坐标private PointF currentPointF;//高度和宽度private int halfHeight;private int width;public MoveCircle(Context context) {super(context);init();}public MoveCircle(Context context, AttributeSet attrs) {super(context, attrs);init();}private void init(){mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setColor(Color.BLUE);halfHeight = ToolUtils.getDisplayMetrics(getContext()).heightPixels/2;width = ToolUtils.getDisplayMetrics(getContext()).widthPixels;currentPointF = new PointF(radius,halfHeight);startAnimator();} @Overrideprotected void onDraw(Canvas canvas) {canvas.drawCircle(currentPointF.x, currentPointF.y, radius, mPaint);super.onDraw(canvas);}/** * 启动动画 */ private void startAnimator() {//使用估值器ValueAnimator,传入一个自定义PositionEvaluator,设置起点坐标,设置终点坐标 ValueAnimator animator = ValueAnimator.ofObject( new PositionEvaluator(),new PointF(radius, halfHeight),new PointF(width-radius, halfHeight));//监听变化过程 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { currentPointF = (PointF) animation.getAnimatedValue(); Log.i("tag"," onAnimationUpdate x: "+currentPointF.x+" y: "+currentPointF.y); invalidate(); } }); // 设置加速插值器AccelerateInterpolator() animator.setInterpolator(new AccelerateInterpolator()); animator.setStartDelay(200);//推迟启动200毫秒 animator.setDuration(10 * 1000).start();//启动 } }</span>
<span style="font-size:14px;">public class PositionEvaluator implements TypeEvaluator<PointF>{private PointF pointF;public PositionEvaluator() {pointF = new PointF();}@Overridepublic PointF evaluate(float fraction, PointF startValue, PointF endValue) {//以正玄曲线从左边运行到右边//x轴:直线运动float x = 0;if (fraction == 0) {x = startValue.x;} else {x = fraction * endValue.x;}// sin(30x-π/2)+1 //y轴:正玄曲线,公式 (float) Math.sin((30 * fraction) - Math.PI/2)+1,其范围是[0,2]float range = (float) Math.sin((30 * fraction) - Math.PI/2)+1;//小球纵坐标+波动范围float y = endValue.y + range*30;pointF.x = x;pointF.y = y;return pointF;} }</span>
0 0
- 属性动画高级用法之TypeEvaluator和Interpolator
- android动画之interpolator和typeEvaluator用法详解
- Android 动画-Interpolator和TypeEvaluator
- Android属性动画(三)——TypeEvaluator(估值器)和Interpolator(插值器)
- 属性动画-TypeEvaluator
- Android属性动画--TypeEvaluator
- 浅析 Android 动画:自定义 Interpolator 与 TypeEvaluator
- Android 属性动画Interpolator和ViewPropertyAnimator的用法
- Android属性动画完全解析,Interpolator和ViewPropertyAnimator的用法
- Android属性动画解析,Interpolator和ViewPropertyAnimator的用法
- 安卓属性动画之插值器(TimeInterpolator)和估值器(TypeEvaluator)
- 走进绚烂多彩的属性动画-Property Animation之TimeInterpolator和TypeEvaluator(下篇)
- 安卓属性动画之插值器(TimeInterpolator)和估值器(TypeEvaluator)
- 属性动画06-Interpolator的用法
- Android开发 之 属性动画(自定义ValueAnimator的TypeEvaluator)
- Android属性动画(下),InterPolator、ViewPropertyAnimator和布局动画的用法
- Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法
- Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法
- CodeForces Gym 100989G Mission in Amman (B)
- 有史来最大改变 Android 5.0十大新特性
- C#简单多线程Demo
- Property Animation
- hbase杂七杂八
- 属性动画高级用法之TypeEvaluator和Interpolator
- leetcode279. Perfect Squares
- Codeforces Round #316 (Div. 2) D DFS+vector+二分
- 记一次debug
- Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /BuildRoot/Library/Cache
- www.wechall.net,一个CTF基础题库学习答案
- fedora 14 安装第三方软件库rpmfusion 出错解决方案
- Win32游戏制作之---致我们曾经怀念的仙剑一
- mysql的order by,group by和distinct优化