您的位置:首页 > 移动开发 > Objective-C

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)));
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动画-android