ValueAnimator及ObjectAnimator的使用
2016-06-14 11:31
429 查看
public class ChangedCircleView extends View { private Round mRound; private Paint mPaint; private int mLength; private int color = Color.RED; public ChangedCircleView(Context context) { super(context); init(); } public ChangedCircleView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ChangedCircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); mPaint.setColor(color); mPaint.setStyle(Paint.Style.FILL); mRound = new Round(50); } /** * ObjectAnimator中何时调用getXxx()方法? * 1) 当且仅当动画的只有一个过渡值时,系统才会调用对应属性的get函数来得到动画的初始值 * 2) 如果没有给定getXxx(),系统会给出警告,并默认初始值为0. */ public int getRoundRadius() { return mRound.radius; } //提供set方法,供objectAnimator反射调用 private void setRoundRadius(int radius) { mRound.radius = radius; invalidate(); } /** * Method setRound() with type class com.bugull.droid.sample.animatior.ChangedCircleView$Round * not found on target class class com.bugull.droid.sample.animatior.ChangedCircleView * * @param round */ private void setRound(Round round) { mRound = round; invalidate(); } private void setColor(int color) { // this.color = color; mPaint.setColor(color); invalidate(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); int desireWith = getDefaultSize(width, widthMeasureSpec); int desireHeight = getDefaultSize(height, heightMeasureSpec); mLength = Math.min(desireHeight, desireWith); setMeasuredDimension(desireWith, desireWith); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); canvas.translate(mLength / 2, mLength / 2); canvas.drawCircle(0, 0, mRound.radius, mPaint); canvas.restore(); } /** * 1) ValueAnimator只负责对指定的数字区间进行动画运算 * 2) 我们需要对运算过程进行监听,然后自己对控件做动画操作 */ public void doValueAnimator() { ValueAnimator animator = ValueAnimator.ofObject(new RoundEvaluator(), new Round(8), new Round(100)); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Round r = (Round) animation.getAnimatedValue(); mRound.radius = r.radius; invalidate(); } }); animator.setDuration(2000); animator.setRepeatCount(ValueAnimator.INFINITE); animator.setRepeatMode(ValueAnimator.REVERSE); animator.setInterpolator(new AccelerateInterpolator()); animator.start(); } /** * ObjectAnimator的实现原理: * 1.加速器产生当前进度的百分比,然后再经过Evaluator生成对应百分比所对应的数字值 * 2.先根据属性值拼装成对应的set函数的名字,,然后通过反射找到对应控件的setXxx()函数,将当前数字值做为setXxx()参数将其传入。 * 3.其中参数类型的确定:靠估值器(Evaluator) * 4.拼接成setXxx()后,反射调用执行了什么:1)重新设置当前控件的参数,2)调用Invalidate()强制重绘; * 5.setXxx()调用频率:动画每隔十几毫秒会刷新一次,set函数也会每隔十几毫秒会被调用一次。 */ public void doObjectAnimator() { ObjectAnimator animator = ObjectAnimator.ofInt(this, "roundRadius", 8, 100); animator.setDuration(1000); animator.setRepeatCount(ValueAnimator.INFINITE); animator.setRepeatMode(ValueAnimator.REVERSE); animator.setInterpolator(new AccelerateInterpolator()); animator.start(); } /** * 使用PropertyValueHolder同时改变view多个属性进行动画: */ public void doHolderAnimator() { PropertyValuesHolder rHolder = PropertyValuesHolder.ofInt("roundRadius", 50, 100); PropertyValuesHolder cHolder = PropertyValuesHolder.ofInt("color", 0xff00ff00, 0xff0000ff); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(this, rHolder, cHolder); animator.setDuration(3000); animator.setRepeatCount(ValueAnimator.INFINITE); animator.setRepeatMode(ValueAnimator.REVERSE); animator.setInterpolator(new AccelerateInterpolator()); animator.start(); } public void doObjectHolderAnimator() { PropertyValuesHolder oHolder = PropertyValuesHolder.ofObject("Round", new RoundEvaluator(), new Round(8), new Round(100)); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(this, oHolder); animator.setDuration(3000); animator.setRepeatCount(ValueAnimator.INFINITE); animator.setRepeatMode(ValueAnimator.REVERSE); animator.setInterpolator(new AccelerateInterpolator()); animator.start(); } /** * 使用关键帧,实现多个动画同时播放 * 对于Keyframe而言,fraction和value这两个参数是必须有的,所以无论用哪种方式实例化Keyframe都必须保证这两个值必须被初始化。 */ public void doKeyFrameAnimator() { Keyframe k1 = Keyframe.ofInt(0, 10); Keyframe k2 = Keyframe.ofInt(0.2F, 50); Keyframe k3 = Keyframe.ofInt(0.5F, 80); Keyframe k4 = Keyframe.ofInt(1.0F, 100); Keyframe f1 = Keyframe.ofInt(0, 0xff0000ff); Keyframe f2 = Keyframe.ofInt(0.2f, 0xff000fff); Keyframe f3 = Keyframe.ofInt(0.4f, 0xff00ffff); Keyframe f4 = Keyframe.ofInt(1.0f, 0xfffff0ff); Keyframe o1=Keyframe.ofObject(0, new Round(10)); Keyframe o2=Keyframe.ofObject(0.3f, new Round(50)); Keyframe o3=Keyframe.ofObject(0.6f, new Round(70)); Keyframe o4=Keyframe.ofObject(1.0f,new Round(100)); PropertyValuesHolder rHolder = PropertyValuesHolder.ofKeyframe("roundRadius", k1, k2, k3, k4); PropertyValuesHolder cHolder = PropertyValuesHolder.ofKeyframe("color", f1, f2, f3, f4); PropertyValuesHolder oHolder=PropertyValuesHolder.ofKeyframe("round",o1,o2,o3,o4); /*使用ofObject必须要设置自定义的Evaluator*/ oHolder.setEvaluator(new RoundEvaluator()); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(this, rHolder, cHolder); animator.setDuration(3000); animator.setRepeatCount(ValueAnimator.INFINITE); animator.setRepeatMode(ValueAnimator.REVERSE); animator.setInterpolator(new AccelerateInterpolator()); animator.start(); } public class Round { public int radius; public Round(int radius) { this.radius = radius; } } private class RoundEvaluator implements TypeEvaluator<Round> { @Override public Round evaluate(float fraction, Round startValue, Round endValue) { int startRadius = startValue.radius; int endRadius = endValue.radius; return new Round((int) (startRadius + fraction * (endRadius - startRadius))); } } }
相关文章推荐
- 用Qt Designer创建ui后,记得修改objectName
- Objective-C文件和目录操作,IOS文件操作,NSFileManager使用文件操作
- mock.patch.object方式写UT
- Python标准库:内置函数hasattr(object, name)
- Xcode报错Expected selector for Objective-C and Expected method body
- Objective-C --- - UITableView 三 自定义cell(梳理总结)
- XString在xml和Object之间来回转换时xml头声明问题
- iOS开发核心语言Objective C语言 —— 特有语法及设计模式
- 彻底解决 libhdf5_hl.so.10: cannot open shared object file: No such file or directory
- Objective-C method ‘application:didFinishLaunchingWithOptions:
- java-map和object装换
- YYModel 源码解读(二)之NSObject+YYModel.h (2)
- 使用_ObjectiveCBridgeable协议实现Objective-C类与Swift结构体的无缝互转
- OpenCV学习Object Segmentation
- Objective-C Runtime 运行时之六:拾遗
- Objective-C Runtime 运行时之五:协议与分类
- Objective-C Runtime 运行时之四:Method Swizzling
- Objective-C Runtime 运行时之二:成员变量与属性
- Objective-C Runtime 运行时之一:类与对象
- Object.entries()