1 Decoation 主要有两个方法
javascript
Path getClipPath(Rect rect, TextDirection textDirection) {
throw UnsupportedError('${objectRuntimeType(this, 'This Decoration subclass')} does not expect to be used for clipping.');
}
less
@factory
BoxPainter createBoxPainter([ VoidCallback onChanged ]);
getClipPath 返回的是裁剪的路径,裁剪的是child的显示区域。Rect 就是Container的范围。
createBoxPainter 返回的是自定义绘制内容的BoxPointer
2 BoxPainter主要是实现下面的方法
arduino
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration);
offset Container 在父节点中的位置
configuration Container的一些信息,包含宽高
最后留下一个demo,裁剪圆形图片
scala
// 自定义装饰:绘制矩形,但裁剪为圆形
class CircleWithRectDecoration extends Decoration {
final Color color;
const CircleWithRectDecoration({required this.color});
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return _CircleWithRectPainter(this, onChanged);
}
@override
Path getClipPath(Rect rect, TextDirection textDirection) {
// 返回圆形裁剪路径
return Path()
..addRect(Rect.fromCenter(center: rect.center, width: rect.width / 2, height: rect.height/2));
}
}
class _CircleWithRectPainter extends BoxPainter {
final CircleWithRectDecoration decoration;
_CircleWithRectPainter(this.decoration, VoidCallback? onChanged) : super(onChanged);
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
final rect = offset & configuration.size!;
final paint = Paint()
..color = decoration.color
..style = PaintingStyle.fill;
// 绘制矩形(而非圆形)
canvas.drawOval(rect, paint);
}
}
使用
less
Container(
width: 150,
height: 150,
clipBehavior: Clip.antiAlias, // 启用裁剪
decoration: const CircleWithRectDecoration(color: Colors.blue),
// 默认 clipBehavior: Clip.none,getClipPath() 无效
child: const FlutterLogo(size: 150),
)