You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中showModalBottomSheet()无法显示模态底部弹窗的问题

解决Flutter中模态底部弹窗无法显示的问题

嘿,我瞅见你这代码里的问题啦!问题出在你调用showModalBottomSheet时用的context不对。

问题原因

你当前传递给startInputAction的context是MyApp这个StatefulWidget的上下文,而它属于MaterialApp层级。showModalBottomSheet需要的是包含在Scaffold内部的上下文——因为它依赖于Scaffold关联的Navigator来管理弹窗的展示逻辑,用MaterialApp的context根本找不到对应的导航栈,自然弹不出窗口。

两种修复方案

方案一:用Builder包裹按钮获取正确的Context

在按钮外层套一个Builder组件,它会提供一个属于Scaffold层级的context,把这个context传给startInputAction即可:

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
  void startInputAction(BuildContext context) {
    showModalBottomSheet(
      context: context,
      builder: (_) {
        return Container(
          height: 200,
          padding: EdgeInsets.all(10),
          child: Text("Something"),
        );
      },
    );
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Error Practice Bottom Sheet"),
          backgroundColor: Colors.purple,
        ),
        body: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              // 添加Builder获取Scaffold层级的context
              Builder(
                builder: (scaffoldContext) {
                  return RaisedButton(
                    color: Colors.purple,
                    padding: EdgeInsets.all(20),
                    child: Text("Click here"),
                    onPressed: () => startInputAction(scaffoldContext),
                  );
                },
              )
            ],
          ),
        ),
      ),
    );
  }
}

方案二:重构Widget结构,调整MaterialApp的位置

把MaterialApp移到main函数里,让MyApp的build方法直接返回Scaffold,这样_MyAppState的context就属于Scaffold层级了:

import 'package:flutter/material.dart';
void main() => runApp(
  // 将MaterialApp移到这里作为根组件
  MaterialApp(
    home: MyApp(),
  ),
);
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
  void startInputAction(BuildContext context) {
    showModalBottomSheet(
      context: context,
      builder: (_) {
        return Container(
          height: 200,
          padding: EdgeInsets.all(10),
          child: Text("Something"),
        );
      },
    );
  }
  @override
  Widget build(BuildContext context) {
    // 直接返回Scaffold,此时context属于Scaffold层级
    return Scaffold(
      appBar: AppBar(
        title: Text("Error Practice Bottom Sheet"),
        backgroundColor: Colors.purple,
      ),
      body: SingleChildScrollView(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              color: Colors.purple,
              padding: EdgeInsets.all(20),
              child: Text("Click here"),
              onPressed: () => startInputAction(context),
            )
          ],
        ),
      ),
    );
  }
}

总结

两种方案都能解决问题,选哪种取决于你的项目结构偏好。核心逻辑都是确保调用showModalBottomSheet时使用的context是Scaffold组件内部的上下文,这样Flutter才能找到正确的导航栈来渲染模态底部弹窗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 18:42:45