Custom Shape for Container

310 views Asked by At

Idea is to make a custom shaped container by giving it ShapeDecoration(). I used this thread as a reference.

Eventialy I achieved the shape I wanted, but once I wrap this custom shaped container with margin\padding\SizedBoxes around it - it's content is being pushed out of the bounds of the container. Check out screenshots.

enter image description here enter image description here

Normaly it should be smth like this: enter image description here

but with paddings between elements.

So the problem is that my customized container behavers realy wierd once it has any margin\padding arround it.

  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:

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:

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();
  }
}
0

There are 0 answers