Reputation: 5064
I am using a bottom navigation bar. On a certain Event trigger I need to show some alert on the current screen.
This is how I have implemented the bottom navigation bar. I have four tabs.
Here, I need to change the icon of the 4th tab when _isHomeDetected
is true and when the user clicks on the icon, i.e on index 3 I have to show an alert message irrespective of which tab the user is in. How do I do this?
class LandingScreen extends StatefulWidget {
static Widget bottomNavigationBar;
..
}
class _LandingScreenState extends State<LandingScreen> {
...
StreamSubscription<String> _subscription;
bool _isHomeDetected = false;
@override
void initState() {
...
_subscription = server.messages.listen(onData, onError: onError);
}
onData(message) {
setState(() {
_isHomeDetected = json.decode(message)["isHomeBeacon"];
});
}
...
@override
Widget build(BuildContext context) {
LandingScreen.bottomNavigationBar = new BottomNavigationBar(
....
);
return new Scaffold(
body: _currentPage,
bottomNavigationBar: LandingScreen.bottomNavigationBar,
);
}
_navigateToScreens(int currentIndex) {
List screens = [
..
];
setState((){
if (!_isHomeDetected || currentIndex != 3){
_currentPage = screens[currentIndex];
} else {
Utils.showCupertinoAlert(
context: context, content: "You wanna log out???");
}
});
}
}
Upvotes: 12
Views: 35255
Reputation: 681
Declare a global key
final globalNavigatorKey = GlobalKey<NavigatorState>();
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
then assign this global key to your MaterialApp
return MaterialApp(
title: 'Flutter Demo',
navigatorKey: globalNavigatorKey,
theme: ThemeData(primarySwatch: Colors.blue,),
home: MyHomePage(),
);
then wherever you want just call example : -
const snackBar = SnackBar(content: Text('Yay! A SnackBar!'));
ScaffoldMessenger.of(globalNavigatorKey.currentContext).showSnackBar(snackBar);
Upvotes: 6
Reputation: 141
Just to elaborate on the answer given by @Ron Geo:
Please note that this answer should be considered if your situation is one where:
The widget you are trying to call showSnackBar
from isn't a child of MaterialApp
.
As an example, this is the case below:
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp();
}
}
Now, if you want App
widget to show a snackbar, the following can be done:
class App extends StatelessWidget {
// 1
GlobalKey<ScaffoldMessengerState> _scaffoldMessengerKey = GlobalKey();
@override
Widget build(BuildContext context) {
return MaterialApp(
// 2
scaffoldMessengerKey: _scaffoldMessengerKey,
);
}
// 3
void showSnackBar() {
_scaffoldMessengerKey.currentState.showSnackBar(....);
}
}
Just to re-iterate this solution is NOT required in most cases where the widget you are calling showSnackBar from is already a child of MaterialApp ... in that case the following code will simply work:
class MyPage extends StatelessWidget {
void showSnackBar() {
ScaffoldMessenger.of(context).showSnackBar(....);
}
}
Upvotes: 2
Reputation: 31
Within the build method of any stateful widget you'll be able to get the build context. If you can't do this, the below sample from flutter team uses a GlobalKey<ScaffoldState>
to hace access to show snackBar alert.
Upvotes: 3