Flutter自定义ShapeBorder和CustomClip

2022-11-16  本文已影响0人  雨泽Sunshine

一.自定义形状ShapeBorder

1.paint方法

@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
}

可以拿到组件的区域信息rect,通过canvas进行图形绘制,比如绘制小小圆:

@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
  final paint = Paint()
    ..strokeWidth = 2
    ..color = Colors.white
    ..style = PaintingStyle.stroke;

  canvas.drawCircle(const Offset(20, 20), 10, paint);

  paint
    ..style = PaintingStyle.fill
    ..color = Colors.black;

  canvas.drawCircle(const Offset(20, 20), 5, paint);
}
绘制圆形

2.getOuterPath方法

@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
  return Path();
}

返回一个Path对象,也就是对形状的裁剪,比如圆角裁剪+打洞:

@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
  final path = Path()
    /// 圆角裁剪
    ..addRRect(RRect.fromRectAndRadius(rect, const Radius.circular(10)))
    /// 打洞
    ..addOval(Rect.fromLTRB(rect.width - 10, 10, rect.width - 30, 30))
    ..fillType = PathFillType.evenOdd;
  return path;
}
圆角裁剪+打洞

二.自定义裁剪CustomClipper

class TicketClipper extends CustomClipper<Path> {
  final double? position;

  final double holeRadius;

  TicketClipper({this.position, this.holeRadius = 16});

  @override
  Path getClip(Size size) {
    final position = this.position ?? size.width - 16;
    if (position > size.width) {
      throw Exception('position is greater than width.');
    }
    final path = Path()
      ..moveTo(0, 0)
      ..lineTo(position - holeRadius, 0.0)
      ..arcToPoint(
        Offset(position, 0),
        clockwise: false,
        radius: const Radius.circular(1),
      )
      ..lineTo(size.width, 0.0)
      ..lineTo(size.width, size.height)
      ..lineTo(position, size.height)
      ..arcToPoint(
        Offset(position - holeRadius, size.height),
        clockwise: false,
        radius: const Radius.circular(1),
      )
      ..lineTo(0.0, size.height)
      ..close();
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => oldClipper != this;
}
CustomClipper
上一篇 下一篇

猜你喜欢

热点阅读