Paint API之—— PathEffect(路径效果)
Paint API 之—— PathEffect (路径效果)
在 Android 绘图中,Paint
类是用于定义绘制样式(如颜色、粗细、风格)的核心工具。其中,PathEffect
是 Paint
的一项高级功能,用于修改路径(Path)的几何形状,在路径被 Canvas 的矩阵变换并绘制之前生效。它可以让简单的直线或曲线变成虚线、波浪线、点状线等效果,常用于 UI 装饰、动画或自定义图形绘制。 简单来说,PathEffect
就像给路径加了一个“滤镜”,让绘制更富有表现力。
PathEffect 的作用与应用场景
- 作用:
PathEffect
影响路径的几何形态,但不改变其整体位置或大小。它只在Paint
的Style
为STROKE
(描边)或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 中的使用),随时告诉我!