Android 画虚线 DashPathEffect 使用详解

本文详细解析了Android中的DashPathEffect,用于创建虚线路径效果。讲解了其构造函数的两个参数含义,重点分析了数组间隔和偏移量对虚线样式的影响,并通过实例展示了不同参数设置下的绘制效果。同时,文章提醒在使用Path时避免调用close方法,以免影响虚线的正确显示。
摘要由CSDN通过智能技术生成

代码

package com.example.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * =======================================================================================
 * Author:caoxinyu
 * createTime:2021_4/7/21_9:28 PM
 * intent:
 * revision history:
 * =======================================================================================
 */

public class PathEffectViewTest extends View {

    private Paint paint;
    private Path path;
    private PathEffect pathEffect;
    private int startY;

    public PathEffectViewTest(Context context) {
        super(context);
        init(context);
    }

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

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

    }

    private void init(Context context) {
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        path = new Path();
        startY = 120;


    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);


        path.moveTo(0, startY);
        path.lineTo(getWidth(),startY);
        pathEffect = new DashPathEffect(new float[]{50,50},0);
        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);



        path.reset();
        path.moveTo(0,startY * 2);
        path.lineTo(getWidth(),startY * 2);
        pathEffect = new DashPathEffect(new float[]{50,10},0);
        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);

        path.reset();
        path.moveTo(0,startY * 3);
        path.lineTo(getWidth(),startY * 3);
        pathEffect = new DashPathEffect(new float[]{50,10,20,10},0);
        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);

        path.reset();
        path.moveTo(0,startY * 4);
        path.lineTo(getWidth(),startY * 4);
        pathEffect = new DashPathEffect(new float[]{50,10},10);
        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);

        path.reset();
        path.moveTo(0,startY * 5);
        path.lineTo(getWidth(),startY * 5);
        pathEffect = new DashPathEffect(new float[]{50,10},-10);
        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);

        path.reset();
        path.moveTo(0,startY * 6);
        path.lineTo(getWidth(),startY * 6);
        pathEffect = new DashPathEffect(new float[]{50,10},-40);
        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);

        path.reset();
        path.moveTo(0,startY * 7);
        path.lineTo(getWidth(),startY * 7);
        pathEffect = new DashPathEffect(new float[]{50,10},60);
        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);



    }
}

画出来的效果

在这里插入图片描述

DashPathEffect 两个参数,我们解释一下:

    public DashPathEffect(float intervals[], float phase) {
        if (intervals.length < 2) {
            throw new ArrayIndexOutOfBoundsException();
        }
        native_instance = nativeCreate(intervals, phase);
    }

第一个参数,数组长度必须大于2,第一位表示实线长度,第二位表示虚线长度,一次类推。
而且必须要是偶数次,如果最后虽然长度大于2,但是不是偶数次,那么最后一次不生效,比如20,10,3 如果使用该数组的话,那么3是不会被使用到的,只会画出来实线20,虚线10 的一条虚线。

第二个参数,表示偏移量。如果是正数,你可以理解为,画完之后,再向左偏移。如果是负数,那么表示向右偏移,此时偏移多出来的长度,会先话虚线,再画实线。

注意:

错误1:使用path 的时候,不要调用close方法

    private void init(Context context) {
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        path = new Path();
        pathEffect = new DashPathEffect(new float[]{20,20},0);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        path.reset();
        path.moveTo(0,40);

        path.lineTo(getWidth(),40);
        path.close();

        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);

    }

如果调用了close 方法,你会发现画出来的线段是这样的。这是因为close 方法会把当前的点和坐标起点连接起来,导致你的画笔会首先从左向右画,然后再从右向左画。
在这里插入图片描述
我们看下close 的源码。


    /**
     * Close the current contour. If the current point is not equal to the
     * first point of the contour, a line segment is automatically added.
     */
    public void close() {
        isSimplePath = false;
        nClose(mNativePath);
    }

所以我们去掉close 方法,再跑一下代码:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        path.reset();
        path.moveTo(0,40);

        path.lineTo(getWidth(),40);

        paint.setPathEffect(pathEffect);
        canvas.drawPath(path,paint);

    }

如下图,我们看到,画出来的是虚线了。
在这里插入图片描述

参考:https://www.jianshu.com/p/0fe69c70be56

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值