flushbar
flushbar copied to clipboard
Push widget upward when snackbar is showing
Hello,
I want to ask if there is any features to these kind of behaviour https://medium.com/@phaniraja/overlap-issue-with-snackbar-df49e25be407
Thank you
Hello @antonygunawan94
So far there are two possible workarounds, but they are not ideal
1- You can give more padding to FLushbar bar so it can go beyond the limits of the view you don't want to obscure. Use aroundPadding
2- Can set overlayBlur
> 0 so the UI don't get confusing.
I don't know if this can be done since we are using a new overlay to show the notification, but I will do some research. This indeed would be a cool feature. Thanks for the feedback.
I had to deal with the same problem and found workaround that works and suits my needs. Preview
The only problem with this solution is that I've couldn't get dimensions and position of flushbar, so tha padding in wrapper is hardcoded and for me works well with my one line fliushbars, but if the size of the flushbar is not constant it should be fitted better.
import 'package:flushbar/flushbar.dart';
import 'package:flushbar/flushbar_route.dart';
import 'package:flutter/material.dart';
class FlushbarRouteObserver extends RouteObserver<PageRoute<dynamic>>
with ChangeNotifier {
FlushbarStatus status;
Flushbar flushbar;
static final FlushbarRouteObserver _instance =
FlushbarRouteObserver._internal();
factory FlushbarRouteObserver() => _instance;
FlushbarRouteObserver._internal();
@override
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
super.didPop(route, previousRoute);
if (route is FlushbarRoute) {
status = route.currentStatus;
flushbar = null;
notifyListeners();
}
}
@override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
super.didPush(route, previousRoute);
if (route is FlushbarRoute) {
flushbar = route.flushbar;
status = route.currentStatus;
notifyListeners();
}
}
}
// Add it to navigatorObservers in MaterialApp
return MaterialApp(
navigatorObservers: [
// ...
FlushbarRouteObserver(),
],
// ...
);
// And create wrapper for FAB widget
class FABWRapper extends StatefulWidget {
@override
FABWRapperState createState() =>
FABWRapperState();
}
class FABWRapperState extends State<FABWRapper> {
EdgeInsets _padding = EdgeInsets.zero;
final flushbarRouteObserver = FlushbarRouteObserver();
@override
void initState() {
super.initState();
flushbarRouteObserver.addListener(_flushbarListener);
}
@override
void dispose() {
flushbarRouteObserver.removeListener(_flushbarListener);
super.dispose();
}
void _flushbarListener() {
EdgeInsets padding;
switch (flushbarRouteObserver.status) {
case FlushbarStatus.IS_APPEARING:
padding = EdgeInsets.only(bottom: 60.0);
break;
case FlushbarStatus.IS_HIDING:
padding = EdgeInsets.zero;
break;
default:
break;
}
setState(() {
_padding = padding;
});
}
@override
Widget build(BuildContext context) {
return AnimatedPadding(
duration: Duration(milliseconds: 450),
padding: _padding,
child: FloatingActionButton(),
);
}
}
I have done it by placing the fab in an AnimatedPositioned which needs to be in a stack. I animate the bottom positon when the FlushBar is appearning or hiding.
floatingActionButton: Stack(
children: [
AnimatedPositioned(
left: 0,
right: 0,
bottom: _bottom,
duration: Duration(seconds: 1),
child: FloatingActionButton(
onPressed: () {
Flushbar(
message: 'Hi There',
flushbarPosition: FlushbarPosition.BOTTOM,
flushbarStyle: FlushbarStyle.FLOATING,
duration: Duration(seconds: 2),
barBlur: 4.0,
onStatusChanged:(status){
print(status);
if(status == FlushbarStatus.IS_APPEARING){
setState(() {
_bottom = 55;
});
}else if(status == FlushbarStatus.IS_HIDING){
setState(() {
_bottom = 0;
});
}
} ,
).show(context);
},
child: Icon(
Icons.category,
color: Colors.black45,
),
backgroundColor: Colors.orangeAccent,
),
),
],
),