6

我们希望在一些异步处理(例如网络进程)之后显示一个 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() {
  }
}

4

3 回答 3

4

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

很少有选项是[1]

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

干杯。

于 2020-12-31T19:15:12.360 回答
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: ...,
    );
  }
}
于 2019-10-24T21:37:58.977 回答
0

您可以应用 Builder 模式概念来简化这一点。

这里有一个小例子。

button_builder.dart

于 2022-01-28T00:21:03.683 回答