Flutter:如何通过代码关闭多层Modal Bottom Sheet?
解决方案
核心思路
不要在打开第二个Sheet前关闭第一个,而是让两个Sheet叠加在导航栈中,这样就能通过Navigator的API分别控制返回/关闭逻辑。
步骤1:正确打开第二个Modal Bottom Sheet
在第一个Sheet内部打开第二个时,直接用当前Sheet的context调用showModalBottomSheet,不要提前pop第一个Sheet:
// 第一个Sheet内打开第二个Sheet的按钮逻辑 onPressed: () { showModalBottomSheet( context: context, builder: (context) => SecondBottomSheet(), ); },
步骤2:实现第二个Sheet的两个按钮逻辑
返回按钮(回到第一个Sheet)
只需要关闭当前的第二个Sheet即可,直接调用一次Navigator.pop(context):
// 第二个Sheet的返回按钮 ElevatedButton( onPressed: () { Navigator.pop(context); // 仅关闭第二个Sheet,回到第一个 }, child: Text("返回"), )
关闭按钮(关闭两个Sheet)
需要一次性清除导航栈中的两个Sheet,有两种常用方式:
- 连续调用两次
pop(逻辑直接,适合确定栈深度的场景):
// 第二个Sheet的关闭按钮 ElevatedButton( onPressed: () { Navigator.pop(context); // 关闭第二个Sheet Navigator.pop(context); // 关闭第一个Sheet }, child: Text("关闭全部"), )
- 使用
popUntil回到根路由(适合不确定栈深度的通用场景):
// 第二个Sheet的关闭按钮 ElevatedButton( onPressed: () { Navigator.of(context).popUntil((route) => route.isFirst); }, child: Text("关闭全部"), )
完整示例片段
// 打开第一个Sheet的按钮 RaisedButton( onPressed: () { showModalBottomSheet( context: context, builder: (context) => FirstBottomSheet(), ); }, child: Text("打开第一个Sheet"), ) // 第一个Sheet组件 class FirstBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: 200, child: Column( children: [ Text("第一个Sheet"), IconButton( icon: Icon(Icons.arrow_forward), onPressed: () { // 直接打开第二个Sheet,不关闭第一个 showModalBottomSheet( context: context, builder: (context) => SecondBottomSheet(), ); }, ) ], ), ); } } // 第二个Sheet组件 class SecondBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: 200, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton( onPressed: () { Navigator.pop(context); // 返回第一个Sheet }, child: Text("返回"), ), ElevatedButton( onPressed: () { // 关闭两个Sheet Navigator.pop(context); Navigator.pop(context); }, child: Text("关闭全部"), ) ], ), ); } }
内容的提问来源于stack exchange,提问作者fazilSizzlers
相关产品推荐
相关产品推荐

