代码
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