Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AlertDialog without context in Flutter

I want to show an AlertDialog when a http get fails. The function showDialog (https://api.flutter.dev/flutter/material/showDialog.html) has the parameter "@required BuildContext context", but I want to call the AlertDialog from my async function getNews(), which hasn't a context value.

By analogy with Java, where I use null for dialog without an owner, I tried to put context value to null, but it is not accepted.

This is my code:

  Future<dynamic> getNews() async {     dynamic retVal;     try {       var response = await http.get(url));       if (response.statusCode == HttpStatus.ok) {         retVal = jsonDecode(response.body);       }     } catch (e) {       alertDlg(?????????, 'Error', e.toString());   }     return     retVal;   }    static Future<void> alertDlg(context, String titolo, String messaggio) async {     return showDialog<void>(         context: context,         barrierDismissible: false, // user must tap button!         builder: (BuildContext context) {         return AlertDialog(               title: Text(titolo),         ...     );   } 
like image 559
Francesco Pagano Avatar asked May 23 '19 18:05

Francesco Pagano


People also ask

How do I show AlertDialog in Flutter?

Create a Flutter project in Android Studio and replace the following code with main. dart file. To show an alert, you must have to call showDialog() function, which contains the context and itemBuilder function. The itemBuilder function returns an object of type dialog, the AlertDialog.

How do you navigate dialog flutters?

You can add a nested Navigator (if you're using Navigator 1.0 in Flutter) by adding the Navigator widget inside your dialog component, that way you manage the navigation of pages within that dialog itself, create nested routes and navigate only within that navigation stack.

How do you style AlertDialog in Flutter?

Edit the the widget itself: Under the AlertDialog there is a ButtonBar widget where you can use alignment: MainAxisAlignment. spaceBetween to align the buttons correctly. See this answer for an example of a custom AlertDialog widget. Show activity on this post.

How does AlertDialog return value in Flutter?

You can access and use the value that comes from your dialog option like this: showDialog( context: context, builder: (context) => Dialog( val: vale, ), ). then((valueFromDialog){ // use the value as you wish print(valueFromDialog); });


Video Answer


1 Answers

Solution without third-party libraries or storing BuildContext:

final navigatorKey = GlobalKey<NavigatorState>();  void main() => runApp(   MaterialApp(     home: HomePage(),     navigatorKey: navigatorKey, // Setting a global key for navigator   ), );  class HomePage extends StatelessWidget {   @override   Widget build(BuildContext context) {     return Scaffold(       appBar: AppBar(),       body: SafeArea(         child: Center(           child: Text('test')         )       ),       floatingActionButton: FloatingActionButton(         onPressed: showMyDialog, // Calling the function without providing it BuildContext       ),     );   } }  void showMyDialog() {   showDialog(     context: navigatorKey.currentContext,     builder: (context) => Center(       child: Material(         color: Colors.transparent,         child: Text('Hello'),       ),     )   ); } 

After setting a global key for navigator (navigatorKey parameter of MaterialApp class), its current state becomes accessible from any part of the code. We can pass its context to the showDialog function. Make sure not to use it before the first frame is built, otherwise the state will be null.

Basically, dialogs are just another type of routes like MaterialPageRoute or CupertinoPageRoute - they are all derived from the ModalRoute class and their instances are pushed into NavigatorState. Context is only needed to get the current navigator's state. A new route can be pushed without having a context if we have a global navigator key:

navigatorKey.currentState.push(route) 

Unfortunately, _DialogRoute class (...\flutter\lib\src\widgets\routes.dart) used in showDialog function is private and unaccessible, but you make your own dialog route class and push it into the navigator's stack.

UPDATE: Navigator.of method has been updated and it's no longer needed to pass subtree context.

like image 120
Igor Kharakhordin Avatar answered Sep 21 '22 08:09

Igor Kharakhordin