首页 > 解决方案 > 容器的自定义形状

问题描述

想法是通过给它 ShapeDecoration() 来制作一个自定义形状的容器。我用这个线程作为参考。

Eventialy 我实现了我想要的形状,但是一旦我用 margin\padding\SizedBoxes 包裹这个自定义形状的容器 - 它的内容就会被推出容器的边界。查看屏幕截图。

在此处输入图像描述 在此处输入图像描述

Normaly它应该是这样的: 在此处输入图像描述

但元素之间有填充。

所以问题是我定制的容器行为者一旦有任何边距\填充,它就真的很奇怪。

  return Padding(
      padding: const EdgeInsets.symmetric(vertical: 40),
      child: Container(
        padding: const EdgeInsets.all(8),
        height: 88,
        alignment: Alignment.center,
        decoration: ShapeDecoration(
          shape: UnitListItemBorderShape(
            color: _isCurrent ? theme.listItemBorderColor : theme.listItemBackgroundColor,
          ),
          color: theme.listItemBackgroundColor,
        ),
        child: Stack(
          children: [
           //custom container's ineer content
          ] ,
      ),
    );

UnitListItemBorderShape 类:

class UnitListItemBorderShape extends ShapeBorder {
  const UnitListItemBorderShape({color}) : _color = color;
  final Color _color;

  @override
  EdgeInsetsGeometry get dimensions => const EdgeInsets.all(0);

  @override
  Path getInnerPath(Rect rect, {TextDirection textDirection}) => null;

  @override
  Path getOuterPath(Rect rect, {TextDirection textDirection}) => UnitListItemShape.getShape(
        rect.width,
        rect.height,
        const Radius.circular(16),
        const Radius.circular(20),
      );

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {
    final Paint borderPaint = Paint()
      ..color = _color
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;
    canvas.drawPath(getOuterPath(rect), borderPaint);
  }

  @override
  ShapeBorder scale(double t) => null;
}

UnitListItemShape 类:

class UnitListItemShape {
  static Path getShape(double width, double height, Radius borderRadius, Radius circleRadius) {
    final double rightOffset = circleRadius.x;
    final Rect rect = Rect.fromCenter(center: Offset(width - rightOffset - 4, height / 2), width: 48, height: 48);
    return Path()
      ..moveTo(borderRadius.x, 0)
      ..lineTo(width - borderRadius.x - rightOffset, 0)
      ..arcToPoint(Offset(width - rightOffset, borderRadius.x), radius: borderRadius)
      ..lineTo(width - rightOffset, (height / 2) - rightOffset - 4)
      // ..addRect(rect)
      ..arcTo(rect, -70 * math.pi / 180, 150 * math.pi / 180, false)
      ..lineTo(width - rightOffset, height - borderRadius.x)
      ..arcToPoint(Offset(width - borderRadius.x - rightOffset, height), radius: borderRadius)
      ..lineTo(borderRadius.x, height)
      ..arcToPoint(Offset(0, height - borderRadius.x), radius: borderRadius)
      ..lineTo(0, borderRadius.x)
      ..arcToPoint(Offset(borderRadius.x, 0), radius: borderRadius)
      ..fillType = PathFillType.evenOdd
      ..close();
  }
}

标签: flutterflutter-container

解决方案


推荐阅读