美文网首页高级UI
Android高级UI——PathMeasure和Matrix

Android高级UI——PathMeasure和Matrix

作者: 谢俊烽 | 来源:发表于2019-11-03 12:21 被阅读0次

    需求是做一个箭头转圈圈的动画

    image
    image.png
    
    public class PathMeasureView extends View {
        private float currentValue = 0;     // 用于纪录当前的位置,取值范围[0,1]映射Path的整个长度
        private Bitmap mBitmap;             // 箭头图片
        private Matrix mMatrix;             // 矩阵,用于对图片进行一些操作
        private Paint mDeafultPaint;
        private int mViewWidth;
        private int mViewHeight;
        private Paint mPaint;
    
        public PathMeasureView(Context context) {
            super(context);
            init(context);
        }
    
        private void init(Context context) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 8;       // 缩放图片
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.arrow, options);
            mMatrix = new Matrix();
    
            mDeafultPaint = new Paint();
            mDeafultPaint.setColor(Color.RED);
            mDeafultPaint.setStrokeWidth(5);
            mDeafultPaint.setStyle(Paint.Style.STROKE);
    
            mPaint = new Paint();
            mPaint.setColor(Color.DKGRAY);
            mPaint.setStrokeWidth(2);
            mPaint.setStyle(Paint.Style.STROKE);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mViewWidth = w;
            mViewHeight = h;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawColor(Color.WHITE);
            // 平移坐标系
            canvas.translate(mViewWidth/2,mViewHeight/2);
            // 画坐标线
            canvas.drawLine(-canvas.getWidth(),0,canvas.getWidth(),0,mPaint);
            canvas.drawLine(0,-canvas.getHeight(),0,canvas.getHeight(),mPaint);
    
            Path path = new Path();                                 // 创建 Path
            /**
             * Path.Direction.CCW 逆时针
             * Path.Direction.CW 顺时针
             */
            path.addCircle(0, 0, 200, Path.Direction.CCW);           // 添加一个圆形
            PathMeasure measure = new PathMeasure(path, false);     // 创建 PathMeasure
    
    //        currentValue += 0.005;                                  // 计算当前的位置在总长度上的比例[0,1]
    //        if (currentValue >= 1) {
    //            currentValue = 0;
    //        }
    
    
            // 获取当前位置的坐标以及趋势的矩阵
            measure.getMatrix(measure.getLength() * currentValue, mMatrix,
            PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);
            // 将图片绘制中心调整到与当前点重合(偏移加旋转)
    //        mMatrix.preTranslate(-mBitmap.getWidth() / 2, -mBitmap.getHeight() / 2);
            canvas.drawPath(path, mDeafultPaint);
            canvas.drawBitmap(mBitmap, mMatrix, mDeafultPaint);
    
            invalidate();
        }
    }
    

    画好坐标轴之后把图片加入到圆圈起点,发现图片选择旋转了90度


    image.png
     mMatrix.preTranslate(-mBitmap.getWidth() / 2, 0);
    

    使图片进行dx的反方向偏移,偏移量是图片宽一半。


    19964945-03afaa49fa74d9a2.webp.jpg

    里面的dx和dy是Matrix的方向,dy表示的是该点偏离圆心的方向,dx表示逆时针切线方向,以dx方向为x轴,dy方向为y轴绘制图片,这也就说明了为啥一开始图片就旋转了90度

     mMatrix.preTranslate(-mBitmap.getWidth() / 2, -mBitmap.getHeight() / 2);
    

    再对dy进行偏移就把箭头移动到轨迹上面了。

    path.addCircle(0, 0, 200, Path.Direction.CCW); 
    

    其中如果将方向改为逆时针Path.Direction.CW,那么Matrix的dx和dy就是,在ccw的基础上改变方向,也就是dy是指向圆心的,dx是顺时针的切线方向,有兴趣的同学自己试一下。

            currentValue += 0.005;                                  // 计算当前的位置在总长度上的比例[0,1]
            if (currentValue >= 1) {
                currentValue = 0;
            }
            ...
            invalidate();//提示系统下一次刷新界面要重新调用一次onDrow
    

    Android 每隔 16.6ms 会刷新一次屏幕,所以每隔16.6ms,currentValue就会增加一次,measure.getLength() * currentValue为一段圆弧的长度,箭头的位置为和起点的距离就是这段圆弧,圆弧不断变长,所以箭头位置就改变一次,
    该部分代码就是不断的调整箭头的位置,也就是让箭头转动起来。

    相关文章

      网友评论

        本文标题:Android高级UI——PathMeasure和Matrix

        本文链接:https://www.haomeiwen.com/subject/wvbkbctx.html