Skip to content

Instantly share code, notes, and snippets.

@nmfisher
Created September 29, 2020 14:52
Show Gist options
  • Save nmfisher/34e8e9852dfef377385892365c61ed94 to your computer and use it in GitHub Desktop.
Save nmfisher/34e8e9852dfef377385892365c61ed94 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class NotchedContainer extends StatelessWidget {
final Widget child;
final Widget notchContent;
final double notchPadding;
final double notchOffsetRight;
final EdgeInsets contentPadding;
final Alignment notchPosition;
final double radius;
final Color color;
NotchedContainer(
{@required this.child,
@required this.radius,
@required this.notchContent,
this.notchPosition = Alignment.topCenter,
this.notchPadding = 5,
this.notchOffsetRight = 0,
this.contentPadding = EdgeInsets.zero,
this.color = Colors.transparent});
Widget _notchContent() {
if (notchPosition == Alignment.topCenter)
return Positioned(
left:0, right:0,
child: notchContent,
);
else if (notchPosition == Alignment.topRight)
return Positioned(
right: notchOffsetRight + notchPadding,
height: radius * 2,
width: radius * 2,
child: notchContent,
);
else
throw Exception("Unsupported notch alignment : $notchPosition ");
}
@override
Widget build(BuildContext context) {
return Stack(children: [
Positioned(
top: radius,
left: 0,
right: 0,
bottom: 0,
child: PhysicalShape(
color: color,
clipBehavior: Clip.hardEdge,
clipper: _NotchClipper(
radius: radius,
padding: notchPadding,
offsetRight: notchOffsetRight,
notchPosition: notchPosition),
child: Container(padding: contentPadding, child: child),
)),
_notchContent()
]);
}
}
class _NotchClipper extends CustomClipper<Path> {
final double offsetRight;
final double padding;
final double radius;
final Alignment notchPosition;
_NotchClipper(
{this.radius, this.padding, this.notchPosition, this.offsetRight = 0});
@override
Path getClip(Size size) {
var shape = AutomaticNotchedShape(ContinuousRectangleBorder(),
RoundedRectangleBorder(borderRadius: BorderRadius.circular(99)));
if (notchPosition == Alignment.topCenter)
return shape.getOuterPath(
Offset.zero & size,
Offset((size.width / 2) - radius - padding, -radius - padding) &
Size((padding + radius) * 2, (padding + radius) * 2));
else if (notchPosition == Alignment.topRight)
return shape.getOuterPath(
Offset.zero & size,
Offset(size.width - ((radius + padding) * 2) - offsetRight, -radius - padding) &
Size((radius + padding) * 2, (radius + padding) * 2));
else
throw Exception("Unsupported notch position $notchPosition");
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment