As I have learnt it from @pskink (thanks for that) in use cases like this where you need the widget to actually adjust its boundaries (spoiler: shape) you should make use of the shape
property of different widgets and use the Path
you used for this example in a custom class which extends ShapeBorder
. Easiest approach would be:
Container(
height: 370,
decoration: ShapeDecoration(
color: Colors.blue,
shape: AppBarBorder(),
/// You can also specify some neat shadows to cast on widgets scrolling under this one
shadows: [
BoxShadow(
color: Colors.black.withOpacity(0.7),
blurRadius: 18.0,
spreadRadius: 2.0,
),
],
),
),
And the custom class:
class AppBarBorder extends ShapeBorder {
@override
Path getOuterPath(Rect rect, {TextDirection textDirection}) {
Offset controllPoint1 = Offset(0, rect.size.height - 100);
Offset endPoint1 = Offset(100, rect.size.height - 100);
Offset controllPoint2 = Offset(rect.size.width, rect.size.height - 100);
Offset endPoint2 = Offset(rect.size.width, rect.size.height - 200);
return Path()
..lineTo(0, rect.size.height)
..quadraticBezierTo(
controllPoint1.dx, controllPoint1.dy, endPoint1.dx, endPoint1.dy)
..lineTo(rect.size.width - 100, rect.size.height - 100)
..quadraticBezierTo(
controllPoint2.dx, controllPoint2.dy, endPoint2.dx, endPoint2.dy)
..lineTo(rect.size.width, 0);
}
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.only(bottom: 0);
@override
Path getInnerPath(Rect rect, {TextDirection textDirection}) => null;
@override
void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {}
@override
ShapeBorder scale(double t) => this;
}
Pretty much the same approach how you would declare a CustomClipper
or CustomPainter
since you don’t need to implement most of those methods and essentially only need to care about getOuterPath
.
At the end we need to restructure the layout itself, since currently you have a Column
with this custom Container
shape and the ListView
beneath that. Since the Container
is not part of the ListView
it can’t be scrolled under or something. Easiest approach would be using a Stack
:
Stack(
children: [
Expanded(
child: ListView(
padding: EdgeInsets.only(top: 370.0),
itemExtent: 100,
children: <Widget>[
Card(
color: Colors.green,
),
],
),
),
Container(
height: 370,
decoration: ShapeDecoration(
color: Colors.blue,
shape: AppBarBorder(),
shadows: [
BoxShadow(
color: Colors.black.withOpacity(0.7),
blurRadius: 18.0,
spreadRadius: 2.0,
),
],
),
),
],
),
CLICK HERE to find out more related problems solutions.