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

来源:互联网 发布:打开xlsx的软件 编辑:程序博客网 时间:2024/04/30 19:34

前言

今天给大家带来的是自定义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<Point> {    /**     * @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 name="PointView">        <attr name="point_color" format="color" /></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中的引用

<com.asiatravel.atpointview.view.PointView        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!

2 0
原创粉丝点击