【问题标题】:MaterialApp builder error : No Overlay widget foundMaterialApp builder错误:未找到覆盖小部件
【发布时间】:2020-07-20 01:35:14
【问题描述】:

我在构建 navigationDrawer 时遇到错误,其中 tootlip 小部件需要 materialApp 作为祖先。

这是错误的意思:

I/flutter ( 5780): _TooltipState#bc79e(ticker inactive)):
I/flutter ( 5780): No Overlay widget found.
I/flutter ( 5780): Tooltip widgets require an Overlay widget ancestor for correct operation.
I/flutter ( 5780): The most common way to add an Overlay to an application is to include a MaterialApp or Navigator
I/flutter ( 5780): widget in the runApp() call.
I/flutter ( 5780): The specific widget that failed to find an overlay was:
I/flutter ( 5780):   Tooltip
I/flutter ( 5780): 
I/flutter ( 5780): The relevant error-causing widget was:
I/flutter ( 5780):   AppBar

我的 ma​​in.dart 代码

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ... //basic info title & theme

      builder: (context, child) => LayoutTemplate(child: child),
      initialRoute:"/home",

      ... //Routing stuff like generate route & navigator key 
    );
  }
}

LayoutTemplate 小部件

class LayoutTemplate extends StatelessWidget {
  final Widget child;

  const LayoutTemplate({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("home"))
        drawer: NavDrawer()
        body: Column(
          children: <Widget>[
            //NavigationBar(),
            Expanded(
              child: child,
            )
          ],
       ),
    );
  }
}

抱歉添加了太多代码。我不确定是什么导致了这个问题。可能是来自MaterialAppbuilder 导致了它。

感谢您的帮助。

【问题讨论】:

  • 总是发布一个我们可以在本地运行的最小可重现代码,我们怎么知道你的slNavigationServicesizingInformationRoutes.clientList等等等等。几乎你的每一行代码使用项目中定义的字段,但您未共享。你在 SO 上快 6 岁了,所以发布一个可以由其他人运行的 MINIMAL REPRODUCIBLE CODE。
  • 我已尝试删除不必要的代码。请检查更新的问题
  • 谢谢,你还能修改initialRouteonGenerateRoutenavigatorKey吗?
  • 我在使用 TextField 而不是 Tooltip 时遇到了非常相似的问题。你找到解决办法了吗?我想我们正在学习相同的教程!

标签: flutter dart flutter-layout


【解决方案1】:

我通过使用 home 而不是 builder 参数解决了这个问题

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ... //basic info title & theme

      home: LayoutTemplate(child: child),
      initialRoute:"/home",

      ... //Routing stuff like generate route & navigator key 
    );
  }
}

【讨论】:

  • 使用 builder(...) 是构建页面的有效方法,如果您将 AppBar 添加到在该构建器中创建的 Scaffold,它应该不会失败。
【解决方案2】:

相反,在您的每条路线中使用您的 LayoutTemplate 小部件:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // ... basic info title & theme

      initialRoute:"/home",
      routes: [
        '/home': (context) => LayoutTemplate(child: Text('Home')),
        // etc, for other routes
      ],
    );
  }
}

builder 参数最适合用于“在Navigator 上方插入[heritable 小部件] 或 - 当使用WidgetsApp.router 构造函数时 - 在Router 上方但在WidgetsApp 创建的其他小部件下方小部件,或用于完全替换 Navigator/Router。"

WidgetsApp.builder 文档:

例如,从传递给[路由构建器方法]的BuildContextDirectionalityLocalizationsDefaultTextStyleMediaQuery等都是可用的。它们也可以被覆盖,从而影响导航器或路由器中的所有路由。

【讨论】:

    【解决方案3】:

    在您的构建器中,只需返回一个带有 LayoutTemplate 作为 OverlayEntry 的 Overlay 小部件。

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          ... //basic info title & theme
    
          builder: (context, child) {
            return Overlay(
              initialEntries: [
                OverlayEntry(
                  builder: (context) => LayoutTemplate(child: child),
                ),
              ],
            );
          },
          initialRoute:"/home",
    
          ... //Routing stuff like generate route & navigator key 
        );
      }
    }
    

    【讨论】:

      【解决方案4】:

      如果您使用的是 responsive_framework: ^0.1.4 包并且遇到了这个问题,那么这里是修复

      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'Flutter App',
            home: MyHomePage(),
            builder: (context, child) {
              return Overlay(
                initialEntries: [
                  OverlayEntry(
                    builder: (context) {
                      return ResponsiveWrapper.builder(
                        MyHomePage(),
                        defaultScale: true,
                        breakpoints: [
                          ResponsiveBreakpoint.autoScale(1000),
                        ],
                      );
                    },
                  ),
                ],
              );
            },
          );
        }
      }
      

      【讨论】:

      • 这行得通,但是如果您只是在响应式框架演示的构建器中删除箭头功能并使用常规功能进行切换,它也可以消除错误。
      猜你喜欢
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 2012-04-10
      • 2019-08-22
      • 2017-10-31
      相关资源
      最近更新 更多