Paint API之—— PathEffect(路径效果)

Paint API 之—— PathEffect (路径效果)

在 Android 绘图中,Paint 类是用于定义绘制样式(如颜色、粗细、风格)的核心工具。其中,PathEffectPaint 的一项高级功能,用于修改路径(Path)的几何形状,在路径被 Canvas 的矩阵变换并绘制之前生效。它可以让简单的直线或曲线变成虚线、波浪线、点状线等效果,常用于 UI 装饰、动画或自定义图形绘制。 简单来说,PathEffect 就像给路径加了一个“滤镜”,让绘制更富有表现力。

PathEffect 的作用与应用场景

  • 作用PathEffect 影响路径的几何形态,但不改变其整体位置或大小。它只在 PaintStyleSTROKE(描边)或 FILL_AND_STROKE(填充+描边)时生效;如果是纯 FILL(填充),则忽略。
  • 应用场景
  • 绘制虚线边框(如按钮轮廓)。
  • 创建波浪或锯齿边缘(装饰文本或形状)。
  • 动画效果(如点状进度条的移动)。
  • 地图路线高亮(自定义线型)。

要使用 PathEffect,只需调用 Paint.setPathEffect(PathEffect effect) 方法设置效果,传入 null 可清除。

PathEffect 的主要子类

PathEffect 是抽象基类,实际使用其子类。以下是常见子类及其用法:

子类描述构造函数示例效果示例
DashPathEffect创建虚线效果,通过交替的“开”和“关”间隔定义虚线模式。phase 参数控制偏移,用于动画。new DashPathEffect(new float[]{10, 5}, 0)(10px 实线 + 5px 间隙)标准虚线
CornerPathEffect为路径直角添加圆角或斜角效果,radius 参数控制圆角半径。new CornerPathEffect(20)(20px 圆角)圆角路径
DiscretePathEffect将路径分成小段并随机偏移,创建“抖动”或手绘感。segmentLength 和 deviation 控制段长和偏移。new DiscretePathEffect(10, 4)(10px 段长,4px 偏移)粗糙线条
PathDashPathEffect用自定义小路径(dash)重复“盖章”在主路径上,style 控制变形方式(TRANSLATE/MORPH/ROTATE)。new PathDashPathEffect(dotPath, 20, 0, PathDashPathEffect.Style.TRANSLATE)点状或自定义图案线
ComposePathEffect组合两个 PathEffect,先应用 inner,再应用 outer。常用于叠加效果。new ComposePathEffect(innerEffect, outerEffect)虚线+圆角

这些子类可以自由组合,创造复杂效果。

代码示例

以下是一个简单的自定义 View 示例,演示多种 PathEffect 的使用。复制到 Android 项目中运行,即可在画布上看到效果。

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.view.View;

public class PathEffectView extends View {
    private Paint paint;

    public PathEffectView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5f);
        paint.setColor(Color.BLACK);
    }

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

        // 示例路径:一个简单的矩形路径
        Path path = new Path();
        path.moveTo(50, 50);
        path.lineTo(200, 50);
        path.lineTo(200, 150);
        path.lineTo(50, 150);
        path.close();

        // 1. 无效果的直线
        canvas.drawPath(path, paint);

        // 2. 虚线效果
        paint.setPathEffect(new DashPathEffect(new float[]{20, 10}, 0));
        Path dashPath = new Path(path); // 复制路径
        canvas.translate(0, 200);
        canvas.drawPath(dashPath, paint);

        // 3. 圆角效果
        paint.setPathEffect(new CornerPathEffect(20f));
        Path cornerPath = new Path(dashPath);
        canvas.translate(0, 200);
        canvas.drawPath(cornerPath, paint);

        // 4. 组合效果:虚线 + 圆角
        PathEffect dash = new DashPathEffect(new float[]{20, 10}, 0);
        PathEffect corner = new CornerPathEffect(20f);
        paint.setPathEffect(new ComposePathEffect(dash, corner));
        Path composePath = new Path(cornerPath);
        canvas.translate(0, 200);
        canvas.drawPath(composePath, paint);

        // 5. 点状效果(用小圆点作为 dash)
        Path dot = new Path();
        dot.addCircle(0, 0, 3, Path.Direction.CW);
        paint.setPathEffect(new PathDashPathEffect(dot, 20, 0, PathDashPathEffect.Style.TRANSLATE));
        Path dotPath = new Path(composePath);
        canvas.translate(0, 200);
        canvas.drawPath(dotPath, paint);
    }
}
  • 运行效果:从上到下依次显示直线、虚线、圆角、虚线圆角组合、点状线。
  • 动画扩展:对于 DashPathEffect 或 PathDashPathEffect,可以通过 ValueAnimator 动态改变 phase 值,实现“流动”虚线效果。

注意事项

  • 性能:复杂 PathEffect(如 PathDashPathEffect)在长路径上可能影响性能,建议在简单路径或低频绘制中使用。
  • 兼容性:API 1+ 支持,无需额外权限。
  • 调试:在 ApiDemos 示例中(SDK 自带)有 PathEffects 演示,可参考。
  • 高级用法:结合 Shader 或 MaskFilter 可创建更炫酷效果,如渐变虚线。

如果需要更多示例代码、特定子类的深入教程,或是 Jetpack Compose 中的等效实现(如 PathEffect 在 Compose 中的使用),随时告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注