Android(安卓)动画机制(二)
Android 动画机制(二)
属性动画(Property animation)
上一篇文章我们介绍了补间动画,最后我们强调了,补间动画只能改变View的绘制效果,View的真实属性是没有变化的,而属性动画可以直接改变View对象的属性值,属性动画的基类Animator 是一个抽象类,所以我们需要集成这个类,并重写其中的方法,Android SDK默认为开发者提供了几个子类。
属性动画的基本属性:
- android:duration 动画的持续时间
- android:interpolator 动画的插值器
- android:repeatMode 动画重复模式
- android:repeatCount 动画重复次数
- setFrameDelay() 设置刷新率
- set标签 设置动画集合
- android:ordering 动画播放顺序,和set联合使用
AnimatorSet
Animator的子类,用来组合多个Animator,并制定这些Animator 是顺序播放还是同时播放
ValueAnimator
Animator的子类,定义了属性动画的大部分功能,包括计算各个帧的属性值、处理更新事件,按照属性值的类型控制计算规则。’’
ObjectAnimator
ValueAnimator的子类,将属性动画帧的值设置给制定的对象,需要注意,在使用ObjectAnimator时,需要为对象实现setter方法。
如果对象是View ,为了能显示动画效果,在某些情况下需要注册AnimatorUpdateListener监听器,并在回调方法onAnimationUpdate中调用View的invalidate 方法来刷新View的显示。
在代码中的使用方法
ValueAnimator.ofFloat() 和ValueAnimator.ofInt()
//ofint() /ofFloat 创建动画实例,将传入的多个Int参数进行平滑过渡:此处传入0和1,表示将值从0平滑过渡到1 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f,1f); valueAnimator.setDuration(2000); valueAnimator.setStartDelay(500);//设置动画延迟播放的时间 valueAnimator.setRepeatCount(0); // ValueAnimator.RESTART(默认):正序重放 ValueAnimator.REVERSE:倒序回放 valueAnimator.setRepeatMode(ValueAnimator.RESTART); // 设置 值的更新监听器 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float curValue = (Float) animation.getAnimatedValue(); Log.i("PropertyAnimator","curValue=="+curValue); //重新绘制布局,实现显示效果的改变,本例并不需要调用requestLayout() view.setScaleX(curValue); view.requestLayout(); } }); valueAnimator.start();
XML 配置
<?xml version="1.0" encoding="utf-8"?>
相关属性介绍:
android:valueFrom:初始值
android:valueTo:结束值
android:valueType:数据类型
android:duration:动画时长
android:startOffset:执行动画前的延时时长
android:fillBefore:动画播放完成后是否恢复到原来的状态,默认为ture。
android:fillAfter:动画播放完成后是否保持当前的状态,默认为false.
android:fillEnabled:是否开启fillBefore,默认为true
android:repeatCount:重复次数
android:repeatMode:重复模式 restart为正序,reverse为倒序
代码中使用方法:
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.property); // 设置动画对象animator.setTarget(imageView);animator.start();
ValueAnimator.ofObject
ValueAnimator.ofInt和ValueAnimator.ofFloat操作的是int和float类型的数据,而ValueAnimator.ofObject改变的是对象,ValueAnimator.ofObject没有默认的插值器,需要开发者自己去实现TypeEvaluator接口来实现自定义插值器。
这里我们使用前辈们的案列解析:
1.根据需要定义插值器:Point是一个简单的坐标对象,实现set和get方法
public class MyTypeValued implements TypeEvaluator{ @Override public Point evaluate(float fraction, Point startValue, Point endValue) { // fraction:表示动画完成度(根据它来计算当前动画的值) // startValue、endValue:动画的初始值和结束值 //计算X,Y的差值 float X=endValue.getX()-startValue.getX(); float Y=endValue.getY()-startValue.getY(); //计算当前point的数值,根据自己的实际需要,计算X,Y的值,这里简单的实现匀速平移 //Point point=new Point(fraction*X+startValue.getX(),fraction*Y+startValue.getY()); //模拟抛物线 float x = 400 * (fraction*1.5f); //坐标x = k * t float y = 400 * (fraction*1.5f) * (fraction*1.5f); //坐标x = k * t *t Point point=new Point(x,y); return point; }}
动画在自定义View中的使用
public class MyView extends View { public static final float RADIUS = 100f;// 圆的半径 private Point currentPoint; private Paint mPaint; public MyView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.BLUE); } // 先在初始点画圆,通过监听当前坐标值(currentPoint)的变化,每次变化都调用onDraw()重新绘制圆,从而实现圆的平移动画效果 @Override protected void onDraw(Canvas canvas) { if (currentPoint == null) { currentPoint = new Point(RADIUS, RADIUS); // 在该点画一个圆 canvas.drawCircle(RADIUS,RADIUS, RADIUS, mPaint); // 创建初始动画时的对象点 & 结束动画时的对象点 Point startPoint = new Point(RADIUS, RADIUS);// 初始点 Point endPoint = new Point(700, 1000);// 结束点 // 创建动画对象 & 设置初始值 和 结束值 ValueAnimator anim = ValueAnimator.ofObject(new MyEvaluator(), startPoint, endPoint); anim.setDuration(5000);//通过 值 的更新监听器,将改变的对象手动赋值给当前对象 anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { // 将每次变化后的坐标值(估值器PointEvaluator中evaluate()返回的Piont对象值)到当前坐标值对象(currentPoint) currentPoint = (Point) animation.getAnimatedValue(); // 调用invalidate()后,就会刷新View,每次赋值后就重新绘制,从而实现动画效果 invalidate(); } }); anim.start(); } else { float x = currentPoint.getX(); float y = currentPoint.getY(); canvas.drawCircle(x, y, RADIUS, mPaint); } }
更多相关文章
- Android中控件绕中心旋转动画
- 分享几个Android很强势的的开源框架
- Android(安卓)内存优化 (防Memory Leak)
- android shape的使用详解
- Android(安卓)NDK编程:数字转string
- Android(安卓)pppd_gprs脚本启动过程
- 使得EditText失去焦点
- [原]Android应用程序绑定服务(bindService)的过程源代码分析
- Android之自定义View:圆形ImageView实现可暂停的旋转动画效果