Android原生绘图(八):PathEffect

2,844 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

1.概念

Paint的setPathEffect函数用于几何绘制时的路径样式,PathEffect是个基类,要实现具体功能需要利用具体的实现类。

PathEffect的实现类包括ComposePathEffect,CornerPathEffect,DashPathEffect,DiscretePathEffect,PathDashPathEffect,SumPathEffect。

各个实现类的作用:

ComposePathEffect和SumPathEffect用于组合两种路径效果,

CornerPathEffect设置路径连线之间的夹角更加平滑,圆润,

DashPathEffect,PathDashPathEffect虚线效果,动态改变会产生动画效果,

DiscretePathEffect会产生一种离散效果,具体就是会在路径上绘制许多杂点。

2.CornerPathEffect

将Path的各个连接线段之间的夹角用一种更平滑的方式连接,一般的,通过CornerPathEffect(float radius)指定一个具体的圆弧半径来实例化一个CornerPathEffect。利用指定半径圆的角替换多个线段之间的连接点,参数radius就是线段之间的圆角的圆滑程度(连接两条直线所使用的圆的半径)

Path mPath1 = new Path();
mPath1.moveTo(150,250);
mPath1.lineTo(250,320);
mPath1.lineTo(300,300);
mPath1.lineTo(350,350);
mPath1.lineTo(420,270);
mPath1.lineTo(540,370);
mPath1.lineTo(560,300);
mPath1.lineTo(650,340);
mPath1.lineTo(750,270);
mPath1.lineTo(850,330);
mPath1.lineTo(950,240);
mPath1.lineTo(1050,290);
mPath1.lineTo(1150,350);
mPath1.lineTo(1250,230);
canvas.drawPath(mPath1, mPaint);

Path mPath2 = new Path();
mPath2.moveTo(150,650);
mPath2.lineTo(250,720);
mPath2.lineTo(300,700);
mPath2.lineTo(350,750);
mPath2.lineTo(420,670);
mPath2.lineTo(540,770);
mPath2.lineTo(560,700);
mPath2.lineTo(650,740);
mPath2.lineTo(750,670);
mPath2.lineTo(850,730);
mPath2.lineTo(950,640);
mPath2.lineTo(1050,690);
mPath2.lineTo(1150,750);
mPath2.lineTo(1250,630);

mPaint.setPathEffect(new CornerPathEffect(30));
canvas.drawPath(mPath2, mPaint);

3. DashPathEffect,PathDashPathEffect

DashPathEffect将Path的线段虚线化

构造函数为DashPathEffect(float[] intervals, float phase),

intervals:是间隔数组,作为实线,虚线的开关,设置虚线实线的长度,该数组的length必须大于等于2,如果设置两个参数就按两个参数循环,第一个参数为“实线长度”,第二个参数为“虚线长度”后面依次循环,还可以设置多个参数(如果是奇数个参数,最后一个参数无效,具体没仔细验证,如果用到大家仔细求证下)。这个PathEffect只对设置Stroke 或者FILL_AND_STROKE 样式的Paint有效,Style为FILL时则失效。

phase为绘制时的偏移量,改变这个值可以实现类似虚实交换的动画效果,phase改变的越大,则动画效果越明显。

Path mPath1 = new Path();
mPath1.moveTo(150,250);
mPath1.lineTo(250,320);
mPath1.lineTo(300,300);
mPath1.lineTo(350,350);
mPath1.lineTo(420,270);
mPath1.lineTo(540,370);
mPath1.lineTo(560,300);
mPath1.lineTo(650,340);
mPath1.lineTo(750,270);
mPath1.lineTo(850,330);
mPath1.lineTo(950,240);
mPath1.lineTo(1050,290);
mPath1.lineTo(1150,350);
mPath1.lineTo(1250,230);
canvas.drawPath(mPath1, mPaint);

Path mPath2 = new Path();
mPath2.moveTo(150,650);
mPath2.lineTo(250,720);
mPath2.lineTo(300,700);
mPath2.lineTo(350,750);
mPath2.lineTo(420,670);
mPath2.lineTo(540,770);
mPath2.lineTo(560,700);
mPath2.lineTo(650,740);
mPath2.lineTo(750,670);
mPath2.lineTo(850,730);
mPath2.lineTo(950,640);
mPath2.lineTo(1050,690);
mPath2.lineTo(1150,750);
mPath2.lineTo(1250,630);

float[] intervals = {50, 20};
mPaint.setPathEffect(new DashPathEffect(intervals,5));
canvas.drawPath(mPath2, mPaint);

PathDashPathEffect

PathDashPathEffect功能类似DashPathEffect,但是它是利用特定的Path形状绘制路径,只有Paint的style是 STROKE or STROKE_AND_FILL时起作用,strokeWidth不影响结果。

构造函数

PathDashPathEffect(Path shape, float advance, float phase,Style style)

参数说明:

shape:路径上的形状,Path内部添加路径形状,类似矩形,三角形等,

advance :两个形状间的距离,如果具体够大可以放好多形状,如果距离过小,只能放置一个形状

phase:偏移距离,和DashPathEffect一样,可以实现动画效果。

4. DiscretePathEffect

这个类的作用术语称为离散路径,使得在原来路径的基础上发生打散效果。

构造函数:

DiscretePathEffect(float segmentLength,float deviation)

segmentLength指定切割的段长,

deviation指定可偏移的距离(离原来的点),越大可偏移的距离越大。

将路径分隔成定长的线段,然后将每条线段随机偏移一段位置,就会产生打散的效果。

mPaint.setPathEffect(new DiscretePathEffect(5,20));
mPaint.setPathEffect(new DiscretePathEffect(10,5));

5.ComposePathEffect与SumPathEffect

ComposePathEffect需要两个PathEffect参数来构造一个实例,
/**
 * Construct a PathEffect whose effect is to apply first the inner effect
 * and the the outer pathEffect (e.g. outer(inner(path))).
 */
ComposePathEffect(PathEffect outerpe, PathEffect innerpe)

作用是先将outerpe的效果作用到路径上,然后再在变换后的路径上添加innerpe效果

SumPathEffect

/**
 * Construct a PathEffect whose effect is to apply two effects, in sequence.
 * (e.g. first(path) + second(path))
 */
public SumPathEffect(PathEffect first, PathEffect second) ;

需要两个PathEffect作为参数,但与ComposePathEffect不同的是,作用是会分别对两个参数的效果各自独立进行表现,然后将两个效果简单的重叠在一起显示出来。

CornerPathEffect cornerPathEffect = new CornerPathEffect(30);
float[] intervals = {50, 20};
DashPathEffect dashPathEffect = new DashPathEffect(intervals, 5);
mPaint.setPathEffect(new ComposePathEffect(cornerPathEffect, dashPathEffect));

mPaint.setPathEffect(new SumPathEffect(cornerPathEffect, dashPathEffect));

1.先圆角,后虚化

2.圆角,虚化,合并