响应式元素与 MediaQuery 对齐 - 使用不包含它的上下文调用

Responsive element alignment with MediaQuery - called with a context that does not contain it

我目前正在设计一个在 dart 中使用 flutter 的应用程序,并且我一直在使用 Flutter Speed Dial 包尝试使用 marginRight 和 marginBottom 值将其对齐到屏幕的左下角。 marginBottom 很简单,但 marginRight 的问题在于,根据屏幕尺寸,相同的静态值最终可能会将小部件放在中心,一直到左边,甚至离开屏幕,具体取决于屏幕尺寸。

所以我调用了 mediaQuery 来获取屏幕尺寸,并以此为基础制作小部件,边距略小于它所在屏幕的宽度,以使值具有响应性。

然而,它说 MediaQuery 是在上下文之外调用的,即使我在 SpeedDial 中调用它,它位于 Scaffold 的 FloatingActionButton 下,设置为 MaterialApp 的主页,如下所示:

Widget build(BuildContext context) {
    return MaterialApp(
      home:Scaffold(
        body: Stack(
            children: [...]
          ),
        floatingActionButton:
        SpeedDial(
          marginRight: MediaQuery.of(context).size.width - 20,
          marginBottom: 65,
          [...]
          children: [
            SpeedDialChild(
                [...]
            ),
            SpeedDialChild(
              [...]
            ),
          ],
        ),
      )
    );
  }

完整错误详述如下:

MediaQuery.of() 使用不包含 MediaQuery 的上下文调用。从传递给 MediaQuery.of() 的上下文开始,找不到任何 MediaQuery 祖先。这可能是因为您没有 WidgetsApp 或 MaterialApp 小部件(这些小部件引入了 MediaQuery),或者如果您使用的上下文来自这些小部件之上的小部件,则可能会发生这种情况。

提前致谢,这让人相当沮丧 :) 非常感谢任何帮助。

要解决您的问题,只需将您的主要小部件包装为 MaterialApp 小部件的 home,如下所示:

main.dart

void main() {
  runApp(
    MaterialApp(home: YourWidget()),
  );
}

并在此处删除 MaterialApp 小部件

yourwidget.dart


class YourWidget extends StatelessWidget {

Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(
            children: [...]
          ),
        floatingActionButton:
        SpeedDial(
          marginRight: MediaQuery.of(context).size.width - 20,
          marginBottom: 65,
          [...]
          children: [
            SpeedDialChild(
                [...]
            ),
            SpeedDialChild(
              [...]
            ),
          ],
        ),
    );
  }
}

您正在丢失上下文,因为 Speeddial 正在使用它自己的上下文。要恢复上下文,您可以使用生成器。

或修改 SpeedDial 以接受 BuildContext。

Widget build(BuildContext context) {
        return MaterialApp(
          home:Scaffold(
            body: Stack(
                children: [...]
              ),
            floatingActionButton: Builder(context) {
           return SpeedDial(
              marginRight: MediaQuery.of(context).size.width - 20,
              marginBottom: 65,
              [...]
              children: [
                SpeedDialChild(
                    [...]
                ),
                SpeedDialChild(
                  [...]
                ),
              ],
            ),
           }
          )
        );
      }