自定义View实现小球斜向下移动

MyView:

    public class MyView extends View {
        // 设置需要用到的变量
        public static final float RADIUS = 70f;// 圆的半径 = 70
        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);
        }
     
        // 复写onDraw()从而实现绘制逻辑
        // 绘制逻辑:先在初始点画圆,通过监听当前坐标值(currentPoint)的变化,每次变化都调用onDraw()重新绘制圆,从而实现圆的平移动画效果
        @Override
        protected void onDraw(Canvas canvas) {
            // 如果当前点坐标为空(即第一次)
            if (currentPoint == null) {
                currentPoint = new Point(RADIUS, RADIUS);
                // 创建一个点对象(坐标是(70,70))
     
                // 在该点画一个圆:圆心 = (70,70),半径 = 70
                float x = currentPoint.getX();
                float y = currentPoint.getY();
                canvas.drawCircle(x, y, RADIUS, mPaint);
     
     
                // (重点关注)将属性动画作用到View中
                // 步骤1:创建初始动画时的对象点  & 结束动画时的对象点
                Point startPoint = new Point(RADIUS, RADIUS);// 初始点为圆心(70,70)
                Point endPoint = new Point(700, 1300);// 结束点为(700,1000)
     
                // 步骤2:创建动画对象 & 设置初始值 和 结束值
                ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
                anim.setInterpolator(new AccelerateInterpolator());
                // 参数说明
                // 参数1:TypeEvaluator 类型参数 - 使用自定义的PointEvaluator(实现了TypeEvaluator接口)
                // 参数2:初始动画的对象点
                // 参数3:结束动画的对象点
     
                // 步骤3:设置动画参数
                anim.setDuration(5000);
                // 设置动画时长
     
                // 步骤3:通过 值 的更新监听器,将改变的对象手动赋值给当前对象
                // 此处是将 改变后的坐标值对象 赋给 当前的坐标值对象
                // 设置 值的更新监听器
                // 即每当坐标值(Point对象)更新一次,该方法就会被调用一次
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        currentPoint = (Point) animation.getAnimatedValue();
                        // 将每次变化后的坐标值(估值器PointEvaluator中evaluate()返回的Piont对象值)到当前坐标值对象(currentPoint)
                        // 从而更新当前坐标值(currentPoint)
                        // 步骤4:每次赋值后就重新绘制,从而实现动画效果
                        invalidate();
                        // 调用invalidate()后,就会刷新View,即才能看到重新绘制的界面,即onDraw()会被重新调用一次
                        // 所以坐标值每改变一次,就会调用onDraw()一次
                    }
                });
     
                anim.start();
                // 启动动画
     
     
            } else {
                // 如果坐标值不为0,则画圆
                // 所以坐标值每改变一次,就会调用onDraw()一次,就会画一次圆,从而实现动画效果
     
                // 在该点画一个圆:圆心 = (30,30),半径 = 30
                float x = currentPoint.getX();
                float y = currentPoint.getY();
                canvas.drawCircle(x, y, RADIUS, mPaint);
            }
        }
     
    }

Point:

    public class Point {
        // 设置两个变量用于记录坐标的位置
        private float x;
        private float y;
     
        // 构造方法用于设置坐标
        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }
     
        // get方法用于获取坐标
        public float getX() {
            return x;
        }
     
        public float getY() {
            return y;
        }
    }

PointEvaluator:

    public class PointEvaluator implements TypeEvaluator<Point> {
        @Override
        public Point evaluate(float fraction, Point startValue, Point endValue) {
            // 将动画初始值startValue 和 动画结束值endValue 强制类型转换成Point对象
            Point startPoint =  startValue;
            Point endPoint =  endValue;
     
            // 根据fraction来计算当前动画的x和y的值
            float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());
            float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());
     
            // 将计算后的坐标封装到一个新的Point对象中并返回
            Point point = new Point(x, y);
            return point;
        }
    }
---------------------
作者:梵韵
来源:CSDN
原文:https://blog.csdn.net/qq_41673194/article/details/80189691
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-06-17 18:29  天涯海角路  阅读(191)  评论(0)    收藏  举报