android弹球动画,Android动画之自定义Evaluator实现弹球效果

前言

今天给大家带来的是自定义Evaluator实现弹球效果,我们先给大家来个效果图。

下面我们介绍具体代码流程

1. 自定义Point类

public class Point {

private int radius;

public Point(int radius) {

this.radius = radius;

}

public int getRadius() {

return radius;

}

public void setRadius(int radius) {

this.radius = radius;

}

}

2. 自定义PointEvaluator实现TypeEvaluator接口

class PointEvaluator implements TypeEvaluator{

/**

*@param fraction 动画变化中的浮点参数,0-1

*@param startValue 动画开始时的Point对象

*@param endValue 动画结束时的Point对象

*@return 动画过程中通过计算获取半径并返回一个新的Point对象

*/

@Override

public Point evaluate(float fraction, Point startValue, Point endValue) {

int startRadius = startValue.getRadius();

int endRadius = endValue.getRadius();

int newRadius = (int) (startRadius + fraction * (endRadius - startRadius));

return new Point(newRadius);

}

}

3. 自定义PointView

定义弹球属性attrs

declare-styleable>

获取自定义属性,这里我们只定义了一个弹球颜色属性。

private void initAttrs(Context context, AttributeSet attrs) {

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PointView);

mColor = typedArray.getColor(R.styleable.PointView_point_color, DEFAULT_COLOR);

typedArray.recycle();

}

初始化画笔

private void initPaint() {

mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setStyle(Paint.Style.FILL);

mPaint.setColor(mColor);

}

重写onMeasure方法

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int widthMode = MeasureSpec.getMode(widthMeasureSpec);

int widthSize = MeasureSpec.getSize(widthMeasureSpec);

int heightMode = MeasureSpec.getMode(heightMeasureSpec);

int heightSize = MeasureSpec.getSize(heightMeasureSpec);

/**

* 测量view的宽高

*/

if (widthMode == MeasureSpec.AT_MOST) {

widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_WIDTH, getResources().getDisplayMetrics()) + getPaddingLeft() + getPaddingRight();

}

if (heightMode == MeasureSpec.AT_MOST) {

heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEIGHT, getResources().getDisplayMetrics()) + getPaddingTop() + getPaddingBottom();

}

/**

* 使用setMeasureDimension方法确定view的最终宽和高

*/

setMeasuredDimension(widthSize, heightSize);

}

在onSizeChanged中获取view的最终宽度和高度

这里minValue是取宽度和高度中的较小值

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

/**

* 在onSizeChanged重载方法中获取view的最终宽度和高度

*/

width = w;

height = h;

/**

* 使用width减去左右的padding

* 使用height减去上下的padding

* 并取两者中的最小值用来确定最大弹球的半径

*/

minValue = Math.min(width - getPaddingLeft() - getPaddingRight(), height - getPaddingTop() - getPaddingBottom());

}

接下来是动画的实现,使用ValueAnimator的ofObject()实现弹球动画

public void startAnimation() {

/**

* 使用ValueAnimator.ofObject()方法并使用自定义的Evaluator实现动画

*/

ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(), new Point(0), new Point(minValue * 2 / 5));

animator.setDuration(2000);

/**

* 设置插值器为BounceInterpolator,其效果为:动画结束的时候弹起

*/

animator.setInterpolator(new BounceInterpolator());

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

/**

* 通过getAnimatedValue获取我们变化中的Point对象

*/

mPoint = (Point) animation.getAnimatedValue();

postInvalidate();

}

});

animator.start();

}

最后是在onDraw函数中绘制弹球

@Override

protected void onDraw(Canvas canvas) {

if (mPoint != null) {

canvas.drawCircle(width / 2, height / 2, mPoint.getRadius(), mPaint);

}

}

4. xml中的引用

android:id="@+id/third_point_view"

android:layout_width="150dp"

android:layout_height="200dp"

android:layout_below="@id/second_point_view"

android:layout_centerHorizontal="true"

android:layout_marginTop="10dp"

android:background="@color/colorPrimary"

app:point_color="#0ff" />

5. 动画实现

在代码中获取PointView的实例然后调用startAnimation()方法实现弹球动画 MainActivity.java

public class MainActivity extends AppCompatActivity {

private PointView pointView;

private PointView secondPointView;

private PointView thirdPointView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

pointView = (PointView) findViewById(R.id.point_view);

secondPointView = (PointView) findViewById(R.id.second_point_view);

thirdPointView = (PointView) findViewById(R.id.third_point_view);

findViewById(R.id.animation_button).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

pointView.startAnimation();

secondPointView.startAnimation();

thirdPointView.startAnimation();

}

});

}

}

总结

以上就是关于今天自定义Evaluator的全部内容,不懂的童鞋可以留言或者发邮件,另外有需要源码的小伙伴可以去github下载,点击跳转到github源码地址,希望大家多多star!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值