Android中的自绘View的那些事儿(八)之 Paint的高级用法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lyz_zyx/article/details/79290167

我们在《Android中的自绘View的那些事儿(一)》中简单介绍过Paint和Canvas的一些常用方法和实例使用。其中,一句话提到Paint中有方法:setStrokeCapsetStrokeJoinsetPathEffect。今天我们就来针对这三个方法来进一步讲解其使用效果。

setStrokeCap

setStrokeCap(Paint.Cap cap);当Paint的setStyle为STROKE或FILL_OR_STROKE时,设置画笔的线冒样式,值有:Cap.BUTTCap.ROUND(圆形样式)和Cap.SQUARE(方形样式)。

示例:

public class MyView extends View {

    private Paint mPaint;

    public MyView(Context context) {
        this(context, null, 0);
    }
    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(0xffff0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(20);
    }

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

        mPaint.setStrokeCap(Paint.Cap.BUTT);
        canvas.drawLine(100, 100, 500, 100, mPaint);

        mPaint.setStrokeCap(Paint.Cap.ROUND);
        canvas.drawLine(100, 200, 500, 200, mPaint);

        mPaint.setStrokeCap(Paint.Cap.SQUARE);
        canvas.drawLine(100, 300, 500, 300, mPaint);
    }
}

效果:


setStrokeJoin

setStrokeJoin(Paint.Join join);当setStyle为STROKE或FILL_OR_STROKE时,设置线段连接处样式,值有:Join.MITER(结合处为锐角)、Join.Round(结合处为圆弧)、Join.BEVEL(结合处为直线) 。

示例:

public class MyView extends View {

    private Paint mPaint;

    public MyView(Context context) {
        this(context, null, 0);
    }
    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(0xffff0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(20);
    }

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

        mPaint.setStrokeJoin(Paint.Join.MITER);
        Path pathA  = new Path();
        pathA.moveTo(100,200);
        pathA.lineTo(500,200);
        pathA.lineTo(500,300);
        canvas.drawPath(pathA, mPaint);

        mPaint.setStrokeJoin(Paint.Join.ROUND);
        Path pathB  = new Path();
        pathB.moveTo(100,500);
        pathB.lineTo(500,500);
        pathB.lineTo(500,600);
        canvas.drawPath(pathB, mPaint);

        mPaint.setStrokeJoin(Paint.Join.BEVEL);
        Path pathC  = new Path();
        pathC.moveTo(100,800);
        pathC.lineTo(500,800);
        pathC.lineTo(500,900);
        canvas.drawPath(pathC, mPaint);
    }
}

效果:


setPathEffect

setPathEffect(PathEffect effect);设置路径样式,其中传值是PathEffect的子类。其中已知子类有:CornerPathEffectDashPathEffectDiscretePathEffectPathDashPathEffectComposePathEffectSumPathEffect

CornerPathEffect(圆角效果)

圆角效果就是拐角处变成圆形,CornerPathEffect(float radius)构造函数接收一个浮点值,它代表拐角处圆的半径。

DashPathEffect(虚线效果)

虚线效果,DashPathEffect(float intervals[], float phase)构造函数接收两个值,第一个参数intervals[]表示组成虚线的一段线段的长度,然后根据此线段来作一个循环组成最终一整条线段。如:new float[] { 10, 5 };则表示虚线中,可见长度是10,间隔长度是5。intervals[]还有两个限制条件:长度必须大于等于2;个数必须是偶数。第二个参数phase表示开始绘制的偏移值,一般为0则可。

DiscretePathEffect(离散效果)

离散效果就是将原来路径分隔成定长的线段,然后将每条线段随机偏移一段位置。DiscretePathEffect(float segmentLength, float deviation)构造函数接收两个值,第一个参数segmentLength表示将原来的路径切成多长的线段。第二个参数deviation表示被切成的每个小线段的可偏移距离。听起来是不是觉得很抽象?不用紧张,稍后看实例效果例会清晰了。

PathDashPathEffect(印章效果)

印章效果就是用另一个路径图案作为印章,沿着线段路径像印章一样盖着连接。PathDashPathEffect(Path shape, float advance, float phase,Stylestyle)构造函数接收四个值,shape表示印章路径;advance表示两个印章之间的距离;phase表示绘制偏移距离;最后style表示遇到转角时的过度效果,值有:Style.ROTATE(旋转印章过渡转角)、Style.MORPH(变形印章过渡转角)和 Style.TRANSLATE(位移印章过渡转角)

ComposePathEffect(合并效果)和 SumPathEffect(叠加效果)

合并效果是把两种样式合并成一种形式。而叠加效果则是直接的把两种样式放在一起。

示例:

public class MyView extends View {

    private Paint mPaint;

    public MyView(Context context) {
        this(context, null, 0);
    }
    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(0xffff0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);
    }

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

        // 圆角效果
        mPaint.setPathEffect(new CornerPathEffect(100));
        Path pathA  = new Path();
        pathA.moveTo(100,10);
        pathA.lineTo(500,10);
        pathA.lineTo(100,110);
        canvas.drawPath(pathA, mPaint);

        // 虚线效果
        mPaint.setPathEffect(new DashPathEffect(new float[] { 20, 10 }, 0));
        Path pathB  = new Path();
        pathB.moveTo(100,160);
        pathB.lineTo(500,160);
        pathB.lineTo(100,260);
        canvas.drawPath(pathB, mPaint);

        // 离散效果
        mPaint.setPathEffect(new DiscretePathEffect(5, 10));
        Path pathC  = new Path();
        pathC.moveTo(100,310);
        pathC.lineTo(500,310);
        pathC.lineTo(100,410);
        canvas.drawPath(pathC, mPaint);

        // 印章效果
        Path stampPath  = new Path();
        stampPath.moveTo(0,20);
        stampPath.lineTo(10,0);
        stampPath.lineTo(20,20);
        stampPath.close();
        mPaint.setPathEffect(new PathDashPathEffect(stampPath, 20, 0, PathDashPathEffect.Style.TRANSLATE));
        Path pathD  = new Path();
        pathD.moveTo(100,460);
        pathD.lineTo(500,460);
        pathD.lineTo(100,560);
        canvas.drawPath(pathD, mPaint);

        // 合并效果
        mPaint.setPathEffect(new ComposePathEffect(new CornerPathEffect(100),  new DashPathEffect(new float[] { 20, 10 }, 0)));
        Path pathE  = new Path();
        pathE.moveTo(100,610);
        pathE.lineTo(500,610);
        pathE.lineTo(100,710);
        canvas.drawPath(pathE, mPaint);

        // 叠加效果
        mPaint.setPathEffect(new SumPathEffect(new CornerPathEffect(100),  new DashPathEffect(new float[] { 20, 10 }, 0)));
        Path pathF  = new Path();
        pathF.moveTo(100,760);
        pathF.lineTo(500,760);
        pathF.lineTo(100,860);
        canvas.drawPath(pathF, mPaint);
    }
}

效果:


猜你喜欢

转载自blog.csdn.net/lyz_zyx/article/details/79290167