Android自定义控件入门到精通--PathEffect路径效果

《Android自定义控件入门到精通》文章索引 ☞ https://blog.csdn.net/Jhone_csdn/article/details/118146683

《Android自定义控件入门到精通》所有源码 ☞ https://gitee.com/zengjiangwen/Code

PathEffect

路径效果,有六个实现类。

在这里插入图片描述

DashPathEffect

DashPathEffect(float intervals[], float phase) 虚线路径效果

  • intervals:描述虚线效果的数组,按这个数组描述循环绘制效果
  • phase:开始绘制的偏移量

示例:

@Override
protected void onDraw(Canvas canvas) {
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.RED);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(4);

    Path path = new Path();
    path.moveTo(50, 50);
    path.lineTo(500, 50);
    paint.setColor(Color.WHITE);
    canvas.drawPath(path, paint);

    canvas.translate(0, 50);
    float[] intervals = new float[]{10, 10};//画10、空10
    paint.setPathEffect(new DashPathEffect(intervals, 0));
    canvas.drawPath(path, paint);

    canvas.translate(0, 50);
    float[] intervals1 = new float[]{10, 30};//画10、空30
    paint.setPathEffect(new DashPathEffect(intervals1, 0));
    paint.setColor(Color.YELLOW);
    canvas.drawPath(path, paint);

    canvas.translate(0, 50);
    float[] intervals2 = new float[]{10, 20, 30, 20};//画10、空20、画30、空20
    paint.setPathEffect(new DashPathEffect(intervals2, 0));
    paint.setColor(Color.RED);
    canvas.drawPath(path, paint);

    canvas.translate(0, 50);
    float[] intervals3 = new float[]{10, 20, 30, 20};//画10、空20、画30、空20
    paint.setPathEffect(new DashPathEffect(intervals3, 30));//起点偏移30
    paint.setColor(Color.RED);
    canvas.drawPath(path, paint);
}

在这里插入图片描述
在这里插入图片描述

用这个phase偏移量还能实现虚线运动的效果

    private Paint mPaint;
    private Path mPath;

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(4);

        mPath = new Path();
        mPath.moveTo(20,120);
        mPath.cubicTo(60,20,180,220,240,120);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawPath(mPath, mPaint);
    }

    //点击事件触发这个方法
    public void showAnimator() {
        ValueAnimator animator = ValueAnimator.ofFloat(0, 45);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setDuration(2000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                mPaint.setPathEffect(new DashPathEffect(new float[]{5, 10, 20, 10}, value));
                invalidate();
            }
        });
        animator.start();
    }

在这里插入图片描述

PathDashPathEffect

PathDashPathEffect(Path shape, float advance, float phase,Style style),图章路径效果

  • shape:图章形状
  • advance:两个图案之间的距离
  • phase:起始偏移量,跟DashPathEffect中的phase一个意思
  • style:设置路径转角图案的处理方式

Style:

  • PathDashPathEffect.Style.TRANSLATE 平移改变位置处理转角
  • PathDashPathEffect.Style.ROTATE 旋转改变角度处理转角
  • PathDashPathEffect.Style.MORPH 变形改变形状处理转角

不知道大家对PS的图案图章工具有没有了解,给大家演示一下:

在这里插入图片描述

PathDashPathEffect路径效果也是差不多是这个样子的

@Override
protected void onDraw(Canvas canvas) {
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.FILL);
    //创建图章形状
    Path shape = new Path();
    shape.moveTo(0, 15);
    shape.quadTo(0, 36, 25, 50);
    shape.quadTo(46, 36, 46, 15);
    shape.cubicTo(46, -2, 25, -2, 23, 12);
    shape.cubicTo(21, -2, 0, -2, 0, 15);

    //创建路径
    Path path = new Path();
    path.moveTo(20, 50);
    path.lineTo(400, 50);
    path.quadTo(300, 300, 200, 200);

    //设置图章效果样式为 Style.TRANSLATE
    mPaint.setPathEffect(new PathDashPathEffect(shape, 80, 0, PathDashPathEffect.Style.TRANSLATE));
    canvas.drawPath(path, mPaint);

    //设置图章效果样式为 Style.ROTATE
    mPaint.setPathEffect(new PathDashPathEffect(shape, 80, 0, PathDashPathEffect.Style.ROTATE));
    canvas.translate(0, 250);
    canvas.drawPath(path, mPaint);

    //设置图章效果样式为 Style.MORPH
    mPaint.setPathEffect(new PathDashPathEffect(shape, 80, 0, PathDashPathEffect.Style.MORPH));
    canvas.translate(0, 250);
    canvas.drawPath(path, mPaint);
}

在这里插入图片描述

CornerPathEffect

CornerPathEffect(float radius),圆角路径效果

  • radius:圆角的半径
@Override
protected void onDraw(Canvas canvas) {
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(2);
    Path path=new Path();
    path.lineTo(100,260);
    path.lineTo(125,60);
    path.lineTo(200,180);
    path.lineTo(250,90);
    path.lineTo(320,200);
    path.lineTo(400,20);
    path.lineTo(499,160);
    //设置圆角路径效果,圆角半径为10
    mPaint.setPathEffect(new CornerPathEffect(10));
    canvas.drawPath(path,mPaint);

    //设置圆角路径效果,圆角半径为50
    mPaint.setPathEffect(new CornerPathEffect(50));
    canvas.translate(0,300);
    canvas.drawPath(path,mPaint);
}

在这里插入图片描述

可以看出,半径越大,圆角越圆润

在这里插入图片描述

SumPathEffect

SumPathEffect(PathEffect first, PathEffect second),几个效果叠加

@Override
protected void onDraw(Canvas canvas) {
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(2);
    //创建一条路径
    Path path = new Path();
    path.lineTo(100, 260);
    path.lineTo(125, 60);
    path.lineTo(200, 180);
    path.lineTo(250, 90);
    path.lineTo(320, 200);
    path.lineTo(400, 20);
    path.lineTo(499, 160);

    //圆角路径效果
    CornerPathEffect cornerPathEffect = new CornerPathEffect(50);
    //虚线路径效果
    DashPathEffect dashPathEffect = new DashPathEffect(new float[]{10, 10}, 0);

    //堆叠效果,圆角效果在下,虚线效果在上
    mPaint.setPathEffect(new SumPathEffect(cornerPathEffect, dashPathEffect));
    canvas.drawPath(path, mPaint);

    //堆叠效果,虚线效果在下,圆角效果在上
    canvas.translate(0, 200);
    mPaint.setPathEffect(new SumPathEffect(dashPathEffect, cornerPathEffect));
    mPaint.setColor(Color.WHITE);
    canvas.drawPath(path, mPaint);
}

在这里插入图片描述

拿上面那条路径来说,也就是先画一条圆角路径效果,再画一条虚线路径效果,然后把两个效果堆叠在一起形成新的一种效果.。

ComposePathEffect

ComposePathEffect(PathEffect outerpe, PathEffect innerpe),复合效果路径

@Override
protected void onDraw(Canvas canvas) {
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(2);
    //创建一条路径
    Path path = new Path();
    path.lineTo(100, 260);
    path.lineTo(125, 60);
    path.lineTo(200, 180);
    path.lineTo(250, 90);
    path.lineTo(320, 200);
    path.lineTo(400, 20);
    path.lineTo(499, 160);

    //圆角路径效果
    CornerPathEffect cornerPathEffect = new CornerPathEffect(50);
    //虚线路径效果
    DashPathEffect dashPathEffect = new DashPathEffect(new float[]{10, 10}, 0);

    //复合效果,先应用虚线路径效果,再在虚线路径效果上应用圆角路径效果
    mPaint.setPathEffect(new ComposePathEffect(cornerPathEffect, dashPathEffect));
    canvas.drawPath(path, mPaint);

    //复合效果,先应用圆角路径效果,再在圆角路径效果上应用虚线路径效果
    canvas.translate(0, 200);
    mPaint.setPathEffect(new ComposePathEffect(dashPathEffect, cornerPathEffect));
    mPaint.setColor(Color.WHITE);
    canvas.drawPath(path, mPaint);
}

在这里插入图片描述

可以看到,跟堆叠效果不一样的是,应用Effect的顺序不一样,最终效果就不一样,这里一定要注意这个顺序了:outer(inner(path)),inner是优先执行的。大家可能会觉得疑问,为什么上面红色路径只有虚线效果,没有圆角效果,这个没有为什么哈,虚线变不圆而已(强行解释)

DiscretePathEffect

DiscretePathEffect(float segmentLength, float deviation),离散路径效果

  • segmentLength :可以理解为离散频率
  • deviation:可以理解为做离散运动的距离,偏移量

例如DiscretePathEffect(2,10),可以理解为:每2个像素长度为单位做离散运动,可运动的最大距离为10

在这里插入图片描述

@Override
protected void onDraw(Canvas canvas) {
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(2);
    //创建一条路径
    Path path=new Path();
    path.lineTo(100,260);
    path.lineTo(125,60);
    path.lineTo(200,180);
    path.lineTo(250,90);
    path.lineTo(320,200);
    path.lineTo(400,20);
    path.lineTo(499,160);

    mPaint.setPathEffect(new DiscretePathEffect(1,0));
    canvas.drawPath(path,mPaint);

    canvas.translate(0,200);
    mPaint.setPathEffect(null);//清除画笔的路径效果

    mPaint.setColor(Color.RED);
    canvas.drawPath(path,mPaint);
    mPaint.setPathEffect(new DiscretePathEffect(1,10));
    mPaint.setColor(Color.WHITE);
    canvas.drawPath(path,mPaint);

    canvas.translate(0,200);
    mPaint.setPathEffect(null);//清除画笔的路径效果
    mPaint.setColor(Color.RED);
    canvas.drawPath(path,mPaint);
    mPaint.setPathEffect(new DiscretePathEffect(10,20));
    mPaint.setColor(Color.WHITE);
    canvas.drawPath(path,mPaint);
}

在这里插入图片描述

可以看到DiscretePathEffect(1,0)的效果,跟本身直线路径没区别,因为按照上面定义的理解,每个像素都做离散运动,运动距离为0,不就等于这个点没有运动吗,所以还是直线。

我们可以通过Paint.setPathEffect(null)来清除画笔的路径效果

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一鱼浅游

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值