如何在 showModalBottomSheet 中获取正确的上下文?

Posted

技术标签:

【中文标题】如何在 showModalBottomSheet 中获取正确的上下文?【英文标题】:How to get the correct context inside a showModalBottomSheet? 【发布时间】:2021-12-02 04:55:33 【问题描述】:

我在一个小部件中有这两个对makeChild(...) 的调用。在树的顶部有一个ChangeNotifierProvider,在makeChild 函数内,我通过Provider.of<...>(context) 访问数据模型。

问题是在 second 调用生成的小部件内部它工作正常,但在 first 一个(对showModalBottomSheet 的调用)它会引发错误说the correct provider couldn't be found above this widget

import 'package:flutter/material.dart';


class PuzzleBox extends StatelessWidget 
  const PuzzleBox(
    Key? key,
    required this.makeChild,
  ) : super(key: key);

  final Function makeChild;

  @override
  Widget build(BuildContext context) 
    return Expanded(
      child: GestureDetector(
        onTap: () 
          showModalBottomSheet(
              context: context,
              builder: (context) => 
                  // THIS DOESN'T HAVE THE RIGHT CONTEXT (PROVIDER NOT FOUND)
                    makeChild(showUI: true),
                  );
        ,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: [
           
            const Divider(height: 24),
            Center(
                child: IgnorePointer(
                  // THIS RENDERS FINE AND HAS THE CORRECT CONTEXT
                    child: FittedBox(child: makeChild(showUI: false)))),
          ],
        ),
      ),
    );
  

换句话说,直接在小部件树中的函数生成一个可以访问我的提供程序的小部件,但showModalBottomSheet 中的相同函数生成一个不能访问的小部件。为什么?

【问题讨论】:

这能回答你的问题吗? How to access Provided (Provider.of()) value inside showModalBottomSheet? 【参考方案1】:

为了避免复杂的代码和传递参数,可以使用 mobx 包:

https://pub.dev/packages/mobx

https://pub.dev/packages/flutter_mobx

https://pub.dev/packages/mobx_codegen

它不需要上下文,因此这将大大简化您的代码,并允许您从任何地方访问提供程序。

您所要做的就是使用正确的注释创建您的提供程序类:@observable@computed@action

并使用 build_runner 生成 dart 文件的一部分,如您将在文档中看到的那样。

在此之后,您必须在全局范围内声明您的提供程序并将其导入以在您想要的地方使用它。

final myProvider = MyClassProvider();

// Anywhereby importing the file where is myProvider

myProvider.value = 'x';

【讨论】:

这与问题无关 MobX 是 Provider 替代品,可用于 showModalBottomSheet、showDialog 等...因为它不需要上下文 这是不正确的。 MobX 是反应式状态管理。 Provider 是一个InheritedWidget,它允许小部件树访问实例。这些是不相同的,因此不是替代方案。您可以使用 Provider 来提供 MobX 存储,而不是按照您的建议创建单例。我的公司离开了 MobX,因为我们发现了太多难以追踪的错误。 如果你在全局范围内声明你的类提供者的一个实例,你将能够在任何你想要的地方使用它。 flutter.dev/docs/development/data-and-backend/state-mgmt/… 正如您在文档中看到的那样,您有一个状态管理列表,其中 Provider 和 MobX 也在哪里,所以我们可以说 MobX 可以成为 Provider 的替代品。

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

如何将数据从 showmodalbottomsheet 传递到 Flutter 中的上一页

如何让 Flutter showModalBottomSheet 动画更快?

Flutter showModalBottomSheet如何调整高度

Flutter showModalBottomSheet如何调整高度

如何将showModalBottomSheet设置为最初的一半高度,但可扩展和可忽略

如何配置 Flutter showModalBottomSheet 开/关动画?