如何画一个像拼图一样的容器

问题描述 投票:0回答:2

我想创建一个如下所示的容器小部件。有人可以帮忙吗?

flutter dart flutter-layout widget
2个回答
2
投票

我正在使用

ShapeBorder

class MyCardShape extends ShapeBorder {
  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.zero;

  @override
  ShapeBorder scale(double t) => this;

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

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    Path path = Path()..fillType = PathFillType.evenOdd;
    const radius = Radius.circular(16);

    final holeGap = rect.height * .15;

    final rrect = RRect.fromRectAndCorners(rect,
        bottomLeft: radius,
        bottomRight: radius,
        topLeft: radius,
        topRight: radius);

    final holePath = Path()
      ..addOval(
        Rect.fromCircle(
          center: Offset(rect.left, rect.top + rect.height / 2),
          radius: holeGap,
        ),
      )
      ..addOval(
        Rect.fromCircle(
          center: Offset(rect.right, rect.top + rect.height / 2),
          radius: holeGap,
        ),
      );

    final path1 = path
      ..addPath(holePath, Offset.zero)
      ..addRRect(rrect);

    final result = path1;
    return result;
  }

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

并使用

ClipRRect
来覆盖多余的形状,您可以选择在绘制上使用 arcToPoint 或其他方法。

class UITest extends StatelessWidget {
  const UITest({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.deepPurple,
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ClipRRect(
            // clipping extra
            child: Container(
              width: 400,
              height: 100,
              clipBehavior: Clip
                  .antiAlias, // not sure why this is not working on shape decoration
              decoration: ShapeDecoration(
                shape: MyCardShape(),
                color: Colors.amber,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

0
投票
    class ContainerClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    final double height = size.height;
    final double width = size.width;
    final double step = height / 10;
    final double offsetX = size.width;
    final double offsetY = size.height;
    final bumpSize = height / 4;

    //position
    path.moveTo(step * 2, step * 2);
    //go down
    path.lineTo(step * 2, step * 4);
    // path.lineTo(step * 2 + width / 3, offsetY);

    path.cubicTo(
      step * 2,
      step * 4,
      step * 0,
      step * 5,
      step * 2,
      step * 6,
    );
    path.lineTo(step * 2, step * 8);
    path.lineTo(step * 4, step * 8);
    path.cubicTo(
      step * 4,
      step * 8,
      step * 5,
      step * 10,
      step * 6,
      step * 8,
    );
    path.lineTo(step * 8, step * 8);
    path.lineTo(step * 8, step * 6);
    path.cubicTo(
      step * 8,
      step * 6,
      step * 6,
      step * 5,
      step * 8,
      step * 4,
    );
    path.lineTo(step * 8, step * 2);
    path.lineTo(step * 6, step * 2);

    path.cubicTo(
      step * 6,
      step * 2,
      step * 5,
      step * 4,
      step * 4,
      step * 2,
    );
    // path.lineTo(step * 8, step * 4);
    // path.lineTo(step * 8, step * 2);
    path.close;
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
© www.soinside.com 2019 - 2024. All rights reserved.