王学岗高级UI7——————PathMeasur的使用(上)

PathMeasure
概念:路径测量,一个用来测量path的工具类
常用API:Path长度测量,path跳转,path片段获取

效果一:

package com.example.testpathmeasure;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * @author writing
 * @time 2019/12/23 13:51
 * @note
 */
public class TestView extends View {

    private Paint deafultPaint;
    private Paint paint;
    private int viewWidth;
    private int viewHeight;

    public TestView(Context context) {
        super(context);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }


    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();

    }

    private void init() {
        deafultPaint = new Paint();
        deafultPaint.setColor(Color.RED);
        deafultPaint.setStrokeWidth(10);
        deafultPaint.setStyle(Paint.Style.STROKE);

        paint = new Paint();
        paint.setColor(Color.DKGRAY);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = w;
        viewHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //平移坐标系
        canvas.translate(viewWidth / 2, viewHeight / 2);
        //画坐标线
        canvas.drawLine(-canvas.getWidth(), 0, canvas.getWidth(), 0, paint);
        canvas.drawLine(0, -canvas.getHeight(), 0, canvas.getHeight(), paint);
        testForceClosed(canvas);
    }

    private void testForceClosed(Canvas canvas) {
        Path path = new Path();
        path.lineTo(0, 200);
        path.lineTo(200, 200);
        path.lineTo(200, 0);
        //如果path是闭合状态,那么无论PathMeasure中的参数是true还是false,都是闭合状态。
        //如果Path是非闭合状态,那么无论PathMeasure中的参数是true,则是闭合状态,false则是非闭合状态。
        PathMeasure pathMeasure1 = new PathMeasure(path, false);
        PathMeasure pathMeasure2 = new PathMeasure(path, true);
        Log.i("zhang_xin", "length of false:" + pathMeasure1.getLength());
        Log.i("zhang_xin", "length or true:" + pathMeasure2.getLength());
        canvas.drawPath(path, deafultPaint);
    }
}

看下打印输出

2019-12-23 14:40:28.234 21174-21174/? I/zhang_xin: length of false:600.0
2019-12-23 14:40:28.234 21174-21174/? I/zhang_xin: length or true:800.0

效果二:

package com.example.testpathmeasure;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * @author writing
 * @time 2019/12/23 13:51
 * @note
 */
public class TestView extends View {

    private Paint deafultPaint;
    private Paint paint;
    private int viewWidth;
    private int viewHeight;

    public TestView(Context context) {
        super(context);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }


    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();

    }

    private void init() {
        deafultPaint = new Paint();
        deafultPaint.setColor(Color.RED);
        deafultPaint.setStrokeWidth(10);
        deafultPaint.setStyle(Paint.Style.STROKE);

        paint = new Paint();
        paint.setColor(Color.DKGRAY);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = w;
        viewHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //平移坐标系
        canvas.translate(viewWidth / 2, viewHeight / 2);
        //画坐标线
        canvas.drawLine(-canvas.getWidth(), 0, canvas.getWidth(), 0, paint);
        canvas.drawLine(0, -canvas.getHeight(), 0, canvas.getHeight(), paint);
 
        testNextContour(canvas);
    }

    private void testNextContour(Canvas canvas) {
        Path path0 = new Path();
        Path path1 = new Path();
        Path path2 = new Path();
        //添加小矩形
        path1.addRect(-100,-100,100,100, Path.Direction.CW);
        PathMeasure pathMeasure1 = new PathMeasure(path1,false);
        Log.i("zhang_xin","path1:"+pathMeasure1.getLength());
        path2.addRect(-200,-200,200,200, Path.Direction.CW);
        /**
         * 对path1与path2进行布尔运算
         * XOP保留path1与path2不共同的部分
         */
        path0.op(path1,path2,Path.Op.XOR);
        canvas.drawPath(path0,deafultPaint);
        PathMeasure pathMeasure = new PathMeasure(path0,false);
        Log.i("zhang_xin","length of pathMeasure:"+pathMeasure.getLength());
    }

   
}

打印输出

2019-12-23 15:24:54.646 26441-26441/com.example.testpathmeasure I/zhang_xin: path1:800.0
2019-12-23 15:24:54.646 26441-26441/com.example.testpathmeasure I/zhang_xin: length of pathMeasure:1600.0

在这里插入图片描述
继续完善我们的代码

package com.example.testpathmeasure;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * @author writing
 * @time 2019/12/23 13:51
 * @note
 */
public class TestView extends View {

    private Paint deafultPaint;
    private Paint paint;
    private int viewWidth;
    private int viewHeight;

    public TestView(Context context) {
        super(context);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }


    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();

    }

    private void init() {
        deafultPaint = new Paint();
        deafultPaint.setColor(Color.RED);
        deafultPaint.setStrokeWidth(10);
        deafultPaint.setStyle(Paint.Style.STROKE);

        paint = new Paint();
        paint.setColor(Color.DKGRAY);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = w;
        viewHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //平移坐标系
        canvas.translate(viewWidth / 2, viewHeight / 2);
        //画坐标线
        canvas.drawLine(-canvas.getWidth(), 0, canvas.getWidth(), 0, paint);
        canvas.drawLine(0, -canvas.getHeight(), 0, canvas.getHeight(), paint);

        testNextContour(canvas);
    }

    private void testNextContour(Canvas canvas) {
        Path path0 = new Path();
        Path path1 = new Path();
        Path path2 = new Path();
        //添加小矩形
        path1.addRect(-100,-100,100,100, Path.Direction.CW);
        PathMeasure pathMeasure1 = new PathMeasure(path1,false);
        Log.i("zhang_xin","path1:"+pathMeasure1.getLength());
        path2.addRect(-200,-200,200,200, Path.Direction.CW);
        Log.i("zhang_xin","path2:"+pathMeasure1.getLength());
        /**
         * 对path1与path2进行布尔运算
         * XOP保留path1与path2不共同的部分
         */
        path0.op(path1,path2,Path.Op.XOR);
        canvas.drawPath(path0,deafultPaint);
        PathMeasure pathMeasure = new PathMeasure(path0,false);
        Log.i("zhang_xin","length of pathMeasure:"+pathMeasure.getLength());

        float[] tan = new float[2];
        float[] pos = new float[2];
        /**
         * diatance 指定Path路径上的长度
         * 两个长度为2的浮点数组,这个数组是用来接收数据
         * tan 当前位置的正切点的XY
         * pos 当前Path路径点的XY
         */
        pathMeasure.getPosTan(50f,pos,tan);
        canvas.drawLine(tan[0],tan[1],pos[0],pos[1],paint);
        Log.i("zhang_xin","tan[0]:"+tan[0]+",tan[1]:"+tan[1]+",pos[0]:"+pos[0]+",pos[1]:"+pos[1]);
        //获取path的长度
        float len1 = pathMeasure.getLength();
        //跳转到下一个路径,由大矩形跳转到小矩形,大矩形与小矩形通过path.op()连接在一起
        pathMeasure.nextContour();
        pathMeasure.getPosTan(50f,pos,tan);
        Log.i("zhang_xin","tan[0]:"+tan[0]+",tan[1]:"+tan[1]+",pos[0]:"+pos[0]+",pos[1]:"+pos[1]);
        canvas.drawLine(tan[0],tan[1],pos[0],pos[1],deafultPaint);
        float len2 = pathMeasure.getLength();
        Log.i("zhang_xin","len1:"+len1);
        Log.i("zhang_xin","len2:"+len2);
    }


}

看下打印输出

2019-12-23 16:45:57.299 32583-32583/com.example.testpathmeasure I/zhang_xin: path1:800.0
2019-12-23 16:45:57.300 32583-32583/com.example.testpathmeasure I/zhang_xin: path2:1600.0
2019-12-23 16:45:57.301 32583-32583/com.example.testpathmeasure I/zhang_xin: length of pathMeasure:1600.0
2019-12-23 16:45:57.302 32583-32583/com.example.testpathmeasure I/zhang_xin: tan[0]:-1.0,tan[1]:0.0,pos[0]:150.0,pos[1]:-200.0
2019-12-23 16:45:57.302 32583-32583/com.example.testpathmeasure I/zhang_xin: tan[0]:-1.0,tan[1]:0.0,pos[0]:50.0,pos[1]:-100.0
2019-12-23 16:45:57.302 32583-32583/com.example.testpathmeasure I/zhang_xin: len1:1600.0
2019-12-23 16:45:57.303 32583-32583/com.example.testpathmeasure I/zhang_xin: len2:800.0

在这里插入图片描述

效果三

package com.example.testpathmeasure;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * @author writing
 * @time 2019/12/23 13:51
 * @note
 */
public class TestView extends View {

    private Paint deafultPaint;
    private Paint paint;
    private int viewWidth;
    private int viewHeight;

    public TestView(Context context) {
        super(context);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }


    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();

    }

    private void init() {
        deafultPaint = new Paint();
        deafultPaint.setColor(Color.RED);
        deafultPaint.setStrokeWidth(10);
        deafultPaint.setStyle(Paint.Style.STROKE);

        paint = new Paint();
        paint.setColor(Color.DKGRAY);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = w;
        viewHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //平移坐标系
        canvas.translate(viewWidth / 2, viewHeight / 2);
        //画坐标线
        canvas.drawLine(-canvas.getWidth(), 0, canvas.getWidth(), 0, paint);
        canvas.drawLine(0, -canvas.getHeight(), 0, canvas.getHeight(), paint);

        testGetSegment(canvas);
    }

    private void testGetSegment(Canvas canvas) {
        Path path = new Path();
        //添加一个顺时针的矩形
        path.addRect(-200,-200,200,200, Path.Direction.CW);
        Path dst = new Path();
        //Path 与 PathMeasure关联
        PathMeasure pathMeasure = new PathMeasure();
        pathMeasure.setPath(path,true);
        //截取一部分保存到dst中,并使用moveTo保持截取到的Path第一个点的位置不变
        pathMeasure.getSegment(200,600,dst,true);
        canvas.drawPath(path,paint);
        canvas.drawPath(dst,deafultPaint);
    }


}

在这里插入图片描述

效果四

看下true与false的区别

package com.example.testpathmeasure;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * @author writing
 * @time 2019/12/23 13:51
 * @note
 */
public class TestView extends View {

    private Paint deafultPaint;
    private Paint paint;
    private int viewWidth;
    private int viewHeight;

    public TestView(Context context) {
        super(context);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }


    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();

    }

    private void init() {
        deafultPaint = new Paint();
        deafultPaint.setColor(Color.RED);
        deafultPaint.setStrokeWidth(10);
        deafultPaint.setStyle(Paint.Style.STROKE);

        paint = new Paint();
        paint.setColor(Color.DKGRAY);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = w;
        viewHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //平移坐标系
        canvas.translate(viewWidth / 2, viewHeight / 2);
        //画坐标线
        canvas.drawLine(-canvas.getWidth(), 0, canvas.getWidth(), 0, paint);
        canvas.drawLine(0, -canvas.getHeight(), 0, canvas.getHeight(), paint);
        testGetSegmentMoveTo(canvas);
    }

    private void testGetSegmentMoveTo(Canvas canvas) {
        Path path = new Path();
        path.addRect(-200,-200,200,200, Path.Direction.CW);
        Path dst = new Path();
        dst.lineTo(300,300);
        
        PathMeasure pathMeasure = new PathMeasure(path,false);
        //tru与fasle会产生两种不同的效果
        pathMeasure.getSegment(200,600,dst,true/false);
        canvas.drawPath(path,paint);
        canvas.drawPath(dst,deafultPaint);
    }
}

为true的时候
在这里插入图片描述
为false的时候
在这里插入图片描述

对PathMeasure中getPosTan不理解的可以看这篇文章

发布了208 篇原创文章 · 获赞 15 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qczg_wxg/article/details/103663430