Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get context in the any function of StatelessWidget?

We want to show an AlertDialog after some asynchronous processing such as network processes.

When calling 'showAlertDialog ()' from an external class, I want to call it without context. Is there a good way?

class SplashPage extends StatelessWidget implements SplashView {
  BuildContext _context;
  @override
  Widget build(BuildContext context) {
    this._context = context;
    ...
  }

I've considered the above method, but I'm worried about side issues.

Help

My current code

class SplashPage extends StatelessWidget implements SplashView {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: MyStoreColors.eats_white1_ffffff,
      body: Center(
        child: new SvgPicture.asset('assets/ic_splash.svg'),
      ),
    );
  }

  @override
  void showAlertDialog() {

    showDialog<void>(
      context: /*How to get context?*/,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Not in stock'),
          content: const Text('This item is no longer available'),
          actions: <Widget>[
            FlatButton(
              child: Text('Ok'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  @override
  void moveToHomeContainer() {
  }

  @override
  void moveToLoginContainer() {
  }
}

like image 675
kyeonghwan Avatar asked Oct 24 '19 14:10

kyeonghwan


People also ask

What is BuildContext context?

BuildContext is a locator that is used to track each widget in a tree and locate them and their position in the tree. The BuildContext of each widget is passed to their build method. Remember that the build method returns the widget tree a widget renders. Each BuildContext is unique to a widget.

What does the context contain in Flutter?

– Context is a link to the location of a widget in the tree structure of widgets. – Context can belong to only one widget. – If a widget has child widgets, then the context of the parent widget becomes the parent context for the contexts of direct child elements.

What is a StatelessWidget?

Stateless Widget: The widgets whose state can not be altered once they are built are called stateless widgets. These widgets are immutable once they are built i.e any amount of change in the variables, icons, buttons, or retrieving data can not change the state of the app.


2 Answers

To show an AlertDialog you need the context, but in StatelessWidget you do not have access to it directly as in StatefulWidget.

Few options are [1]:

  • passing it as GlobalKey [2]
  • passing build context as parameter to any other function inside StatelessWidget
  • use a service to inject the dialog without context [3]

Cheers.

like image 77
J. Pablo García Avatar answered Oct 23 '22 13:10

J. Pablo García


You should trigger rebuild when the async event complete, either convert your widget to StatefulWidget and call setState() or use a state management solution like Bloc.

For example using StatefulWidget your code will look like this:

class SplashPage extends StatefulWidget {
  @override
  State<SplashPage> createState() => _SplashPageState();
}

class _SplashPageState extends State<SplashPage> implements SplashView {

  bool _asynOpDone = false;

  /// Call this when the async operation is done.
  void _onAsynOpDone() => setState(() => _asyncOpDone = true);

  @override
  Widget build(BuildContext context) {
    if (_asyncOpDone) showAlertDialog(context);

    return Scaffold(
      ...,
      ///
    );
  }

  @override
  void showAlertDialog(BuildContext context) {
    showDialog<void>(
      context: context,
      builder: ...,
    );
  }
}
like image 29
Gan Quan Avatar answered Oct 23 '22 13:10

Gan Quan