Issue
I was dealing with the ScaffoldMessenger.of(context).showMaterialBanner
method and it needs a MaterialBanner widget as parameter.
Goal
In my case I need to put an empty MaterialBanner widget but with a custom height (less than default).
In few words override the original MaterialBanner build method.
What I tried
so I thought that I had to extend a StatefulWidget implementing MaterialBanner:
class MiniBanner extends StatefulWidget implements MaterialBanner {
const MiniBanner({Key? key}) : super(key: key);
@override
List<Widget> get actions => [const SizedBox()];
@override
Animation<double>? get animation => null;
@override
Color? get backgroundColor => Colors.amber;
@override
Widget get content => const SizedBox();
@override
TextStyle? get contentTextStyle => null;
@override
double? get elevation => 0;
@override
bool get forceActionsBelow => false;
@override
Widget? get leading => null;
@override
EdgeInsetsGeometry? get leadingPadding => EdgeInsets.zero;
@override
VoidCallback? get onVisible => null;
@override
OverflowBarAlignment get overflowAlignment => OverflowBarAlignment.end;
@override
EdgeInsetsGeometry? get padding => EdgeInsets.zero;
@override
MaterialBanner withAnimation(Animation<double> newAnimation, {Key? fallbackKey}) {
return MaterialBanner(
key: key ?? fallbackKey,
content: content,
contentTextStyle: contentTextStyle,
actions: actions,
elevation: elevation,
leading: leading,
backgroundColor: backgroundColor,
padding: padding,
leadingPadding: leadingPadding,
forceActionsBelow: forceActionsBelow,
overflowAlignment: overflowAlignment,
animation: newAnimation,
onVisible: onVisible,
);
}
@override
State<MiniBanner> createState() => _MiniBannerState();
}
class _MiniBannerState extends State<MiniBanner> {
@override
Widget build(BuildContext context) {
// I want the code to go here to build a smaller MaterialBanner
return Container(
color: widget.backgroundColor,
height: 10,
);
}
}
But my code keep going to the original MaterialBanner method. Maybe I'm missing some knowledge about extending stateful widgets.
Solution
Solved
The main issue was the return type of the "withAnimation" method. It has to be the same type of your custom widget. So:
class MiniBanner extends StatefulWidget implements MaterialBanner {
const MiniBanner({
Key key,
this.content = const SizedBox(),
this.contentTextStyle,
this.actions = const [SizedBox()],
this.elevation = 0,
this.leading,
this.backgroundColor = Colors.red, //custom default color
this.padding = EdgeInsets.zero,
this.leadingPadding = EdgeInsets.zero,
this.forceActionsBelow = false,
this.overflowAlignment = OverflowBarAlignment.end,
this.animation,
this.onVisible,
}) : assert(elevation == null || elevation >= 0.0),
assert(content != null),
assert(actions != null),
assert(forceActionsBelow != null),
super(key: key);
@override
final List<Widget> actions;
@override
final Animation<double> animation;
@override
final Color backgroundColor;
@override
final Widget content;
@override
final TextStyle contentTextStyle;
@override
final double elevation;
@override
final bool forceActionsBelow;
@override
final Widget leading;
@override
final EdgeInsetsGeometry leadingPadding;
@override
final VoidCallback onVisible;
@override
final OverflowBarAlignment overflowAlignment;
@override
final EdgeInsetsGeometry padding;
@override
MiniBanner withAnimation(Animation<double> newAnimation, {Key fallbackKey}) {
return MiniBanner(
key: key ?? fallbackKey,
content: content,
contentTextStyle: contentTextStyle,
actions: actions,
elevation: elevation,
leading: leading,
backgroundColor: backgroundColor,
padding: padding,
leadingPadding: leadingPadding,
forceActionsBelow: forceActionsBelow,
overflowAlignment: overflowAlignment,
animation: newAnimation,
onVisible: onVisible,
);
}
@override
State<MiniBanner> createState() => MiniBannerState();
}
class MiniBannerState extends State<MiniBanner> {
@override
Widget build(BuildContext context) {
// Now our MiniBanner correctly build this method
return Container(
color: widget.backgroundColor,
height: 10,
);
}
}
Important note
This code is not null sound safety so if you have a Flutter application with null sound safety enabled you have to change some syntax, like adding ? after the nullable properties and so on.
UPDATE
If you want to really emulate the original MaterialBanner with all the animations, you have to copy almost the entire original "build" method.
Then, to custom your widget, you just have to edit the assignment of materialBanner
variable, example:
// other parts of code copied from original build method above
Widget materialBanner = Container(
color: widget.backgroundColor,
height: 10,
);
// other parts of code copied from original build method below
Answered By - Marco Rossi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.