如何在 StatelessWidget 的任何函数中获取上下文?

Posted

技术标签:

【中文标题】如何在 StatelessWidget 的任何函数中获取上下文?【英文标题】:How to get context in the any function of StatelessWidget? 【发布时间】:2020-02-20 21:32:25 【问题描述】:

我们希望在一些异步处理(例如网络进程)之后显示一个 AlertDialog。

当从外部类调用“showAlertDialog()”时,我想在没有上下文的情况下调用它。有什么好办法吗?

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

我考虑过上述方法,但我担心会出现一些问题。

帮助

我当前的代码

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() 
  


【问题讨论】:

你会在哪里使用showAlertDialog?您可以将context 作为参数传递 是的,你为什么不使用showAlertDialog(BuildContext context) 我尝试使用类似于 MVP 的架构。在此页面中,我想在视图绑定到演示者时检查应用程序版本。并且想在presenter中将版本检查的错误信息输出到view.showAlertDialog() 您是说在build() 中调用presenter.checkAppVersion(context) 吗? 【参考方案1】:

要显示 AlertDialog,您需要上下文,但在 StatelessWidget 中,您无法像在 StatefulWidget 中那样直接访问它。

很少有选项是[1]:

将其作为 GlobalKey [2] 传递 将构建上下文作为参数传递给 StatelessWidget 中的任何其他函数 使用服务注入没有上下文的对话框[3]

干杯。

【讨论】:

【参考方案2】:

您应该在异步事件完成时触发重建,将您的小部件转换为 StatefulWidget 并调用 setState() 或使用 Bloc 等状态管理解决方案。

例如使用StatefulWidget,您的代码将如下所示:

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: ...,
    );
  

【讨论】:

此页面是一个介绍屏幕,只有一个图像视图。一旦构建,视图就不需要重建。顺便说一句,我应该使用 StatefulWidget 来调出 AlertDialog 吗?我认为还有另一种好方法。

以上是关于如何在 StatelessWidget 的任何函数中获取上下文?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 StatelessWidget 中更改 StatefulWidget 的状态?

StatelessWidget 与在性能方面返回 Widget 的函数

如何将数据从 StatelessWidget 传递到 StatefulWidget?

调用 Statelesswidget 中的方法以获取启动画面?

Flutter:如何将变量从 StatelessWidget 传递到 StatefulWidget

如何从 StatelessWidget 中的 StatefulWidget 访问变量?