TLDR:
Use ModalRoute.of(context).isCurrent
to determine if the current context is visible and pass the scaffolkey in the widget's build method.
Details
My application is slightly different but I believe my solution is still applicable.
In my application I have several Providers that run across different pages but may all need to raise a snackbar. Hence the provider needs to know which scaffold is active.
I have discovered and made use of ModalRoute.of(context).isCurrent
which allows you to determine if the current context is visible.
I created the following mixin:
import 'package:flutter/material.dart';
mixin SnackBarHandler {
GlobalKey<ScaffoldState> _scaffoldKey;
/// Sets the scaffold key if the caller is active.
void setSnackBarContext(
BuildContext context, GlobalKey<ScaffoldState> scaffoldKey) {
if (ModalRoute.of(context).isCurrent) {
_scaffoldKey = scaffoldKey;
}
}
/// Convenience wrapper to show snack bar.
void showSnackbar(SnackBar snackBar) {
_scaffoldKey?.currentState?.showSnackBar(snackBar);
}
}
Which is added to any class you need to show snack bars from as follows:
class BleDeviceProvider extends ChangeNotifier with SnackBarHandler{
showSnackbar(SnackBar());
}
Each page that you want to show snack bars from the call above must include the following in their build:
Widget build(BuildContext context) {
return Consumer<BleDeviceArc003Provider>(
builder: (_, bleDeviceArc003Provider, __) {
bleDeviceArc003Provider.setSnackBarContext(context, _scaffoldKey);
return WillPopScope(
onWillPop: _onPop,
child: Scaffold(
key: _scaffoldKey,
appBar: AppBar(),
body: ListView()
),
}
});
}