You need to enable JavaScript to run this app. Flutter自定义AppBar调用Scaffold.of()无法获取上下文报错求助
优惠活动
大模型
产品
解决方案
定价
更多

Flutter自定义AppBar调用Scaffold.of()无法获取上下文报错求助

错误原因

你调用Scaffold.of()时传入的context来自MyApp的build方法,此时这个context对应的组件树节点,还没有将你创建的Scaffold作为祖先节点——因为这个Scaffold本身就是MyApp.build方法返回的子组件,从这个context往上遍历自然找不到Scaffold实例。

解决方案1:拆分主页组件(官方推荐)

把Scaffold所在的页面抽成单独的StatelessWidget,新组件的build方法拿到的context就会包含上层的Scaffold了。
修改main.dart代码:

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Food App',
        theme: ThemeData(
          primaryColor: kPrimaryColor,
          scaffoldBackgroundColor: Colors.white,
        ),
        // 把Scaffold移到单独的HomePage组件里
        home: HomePage()
    );
  }
}

// 新增单独的主页组件
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavBar(),
      body: HomeScreen(),
      drawer: CustomDrawer(),
      // 这里传入的context是HomePage的,父级已经有Scaffold了
      appBar: homeAppBar(context),
    );
  }
}

你后续写的无回调版本的homeAppBar代码不需要修改,可直接使用。

解决方案2:用Builder包裹AppBar(无需修改现有组件逻辑)

你之前尝试用Builder报错是因为放置位置不对,不需要在homeAppBar内部包裹,只要在给Scaffold的appBar参数赋值时外层套Builder即可,Builder会生成一个位于Scaffold子层级的新context:

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Food App',
        theme: ThemeData(
          primaryColor: kPrimaryColor,
          scaffoldBackgroundColor: Colors.white,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavBar(),
          body: HomeScreen(),
          drawer: CustomDrawer(),
          // 外层加Builder,传入子层级的新context
          appBar: Builder(
            builder: (childContext) => homeAppBar(childContext),
          ),
        ));
  }
}

该方案下你写的无回调版本homeAppBar也可以直接使用。

解决方案3:给Scaffold绑定GlobalKey

如果不想调整组件结构,也可以直接给Scaffold指定全局key,通过key直接调用openDrawer方法,不需要依赖context查找:
修改main.dart代码:

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // 定义Scaffold的全局Key
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Food App',
        theme: ThemeData(
          primaryColor: kPrimaryColor,
          scaffoldBackgroundColor: Colors.white,
        ),
        home: Scaffold(
          // 给Scaffold绑定key
          key: _scaffoldKey,
          bottomNavigationBar: BottomNavBar(),
          body: HomeScreen(),
          drawer: CustomDrawer(),
          appBar: homeAppBar(_scaffoldKey, context),
        ));
  }
}

对应修改homeAppBar的入参:

AppBar homeAppBar(GlobalKey<ScaffoldState> scaffoldKey, BuildContext context) {
  return AppBar(
    backgroundColor: Colors.white,
    elevation: 0,
    leading: IconButton(
      icon: SvgPicture.asset("assets/icons/menu.svg"),
      // 直接通过key调用打开抽屉方法
      onPressed: () => scaffoldKey.currentState?.openDrawer(),
    ),
    // 其余代码保持不变
    title: RichText(
      text: TextSpan(
        style: Theme.of(context)
            .textTheme
            .headline6
            ?.copyWith(fontWeight: FontWeight.bold),
        children: [
          TextSpan(
            text: "Makana",
            style: TextStyle(color: ksecondaryColor),
          ),
          TextSpan(
            text: "Food",
            style: TextStyle(color: kPrimaryColor),
          ),
        ],
      ),
    ),
    actions: <Widget>[
      IconButton(
        icon: SvgPicture.asset("assets/icons/notification.svg"),
        onPressed: () {},
      ),
    ],
  );
}

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 09:36:04