'How can I show a snackbar after navigator.pop(context) in Flutter?
We need close one screen and open a second screen. And show snackbar on the second screen from first screen.
I tried to use Navigator.push
, but this screen is already open and we have this error
Bad state: Stream has already been listened to.
Solution 1:[1]
Instead of Snackbar i would suggest you to use Flushbar plugin for flutter it is easy to use and it'll take care of everything and u can customize it to a great extent . Snackbar needs a scaffold ancestor to work but Flushbar doesn't and it takes care of all the extra stuff itself and provides with ton of cool features.
Solution 2:[2]
I'm not sure I understand 100% the use case you have but by returning results from screens and passing arguments to new routes, you can work around basically any scenario.
Let's take an example. A is the original screen, then you push screen B. Now you see B, perform some action there, pop it, you get back to screen A and you want to display a snackbar.
When you pop
, you can return a result and handle that result from the "parent" screen as described in the "Return data from a screen" cookbook.
When you receive a result, you can either show a snackbar notification, or alternatively (in case there is a third screen), you can pass that result to another screen as argument.
Solution 3:[3]
showSubmitRequestSnackBar(BuildContext context) async {
Flushbar(
flushbarPosition: FlushbarPosition.BOTTOM,
message: "Request Successfully Saved",
icon: Icon(
Icons.info_outline,
size: 28.0,
color: Colors.red,
),
backgroundColor: Colors.red,
duration: Duration(seconds: 5),
leftBarIndicatorColor: Colors.red,
)
..show(context).then((r)=> Navigator.push(
context, MaterialPageRoute(builder: (context) => ListPage(""))));
}
Solution 4:[4]
Screen A
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BScreen(
callbackFunction: (String resMessage){
print(resMessage);
},
),
),
);
Screen B
class BScreen extends StatefulWidget {
final Function callbackFunction;
BScreen({required this.callbackFunction});
@override
_BScreenState createState() => _BScreenState();
}
class _BScreenState extends State<BScreen> {
//
_performTask(){
// add your task here
// ..........
String msg = 'Task has been added';
widget.callbackFunction(msg);
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
_performTask();
},
child: Text('Click Here'),
),
),
);
}
}
This solution worked for me. Happy to help others :) Thanks for asking this question.
Solution 5:[5]
Please read this documentation by Flutter that answers your question with example.
What you have to do is, when you are going to Navigator.pop
you can pass a message and based on that message you can show SnackBar
in the previous screen where you did Navigator.push
So when you pop do something like this:
Navigator.pop(context, 'Yes');
Navigator.pop(context, 'No');
Here, you are passing a message and based on this message you can show the Snackbar in the previous screen where you pushed like this:
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
// After the Selection Screen returns a result, hide any previous snackbars
// and show the new result.
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text('$result')));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Vince Varga |
Solution 3 | |
Solution 4 | Kamlesh |
Solution 5 | MD. Saffan Alvy |