Flutter:在/替换底部导航栏时显示模态底部表(无屏障)

8
我正在尝试为自己的Flutter应用程序复制类似于Google Maps的某些功能。同样基于地图,我希望用户能够选择感兴趣的点,并有导航到该位置的选项。
当他们点击“导航”时,我希望一个底部工作表出现在我为基于选项卡的导航而拥有的现有底部导航栏的位置(或上方)。 showModalBottomSheet()可以做到这一点,但它有一个屏障,防止用户与父视图交互。我需要没有这个屏障。 showBottomSheet()没有这个屏障,但也没有放置在底部导航栏之上。
是否有一些解决方案以实现这种功能?我唯一能想到的是将底部导航栏添加到容器中,根据用户是否正在导航来显示/隐藏,但我觉得这是一个相当糟糕的解决方案,并希望有更优雅的解决方案。
我附上了下面的一些图片:
  • 第一张截图显示了iOS上Google Maps的标准视图,带有底部导航栏。
  • 第二张截图显示了“预导航”视图,这是一个底部工作表,放置在底部导航栏的顶部(或代替它)。这是我试图复制的视图。

This is the main view with the Bottom Navigation Bar at the bottom

This is the 'pre-navigation' view that shows a bottom sheet without / on top of the Bottom Navigation Bar


你找到了好的解决方案吗?我也有同样的问题 :D - Marc Sanny
1
最终我做了与Guillaume下面回答类似的事情。我将包含BottomNavigationBar的Scaffold包装成了一个Stack小部件,然后在其上添加了自定义导航视图,并设置其在用户进入“导航模式”时出现。我已经在下面发布了我的代码。https://dev59.com/NL_qa4cB1Zd3GeqPMahL#68208539 - Andy Shephard
3个回答

14

showBottomModalSheet中使用useRootNavigator: true


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

5
我找到的解决方法是将包含底部导航栏的Scaffold小部件包装在另一个Scaffold中。思路是在父级Scaffold内显示模态框,以便它位于子Scaffold内的bottomNavigationBar上方。
class _MyWidgetState extends State<MyWidget> {
  bool _showModal = false;
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  PersistentBottomSheetController _bottomSheetController;

  void _showOrHide(bool show) {
    _showModal = show;
    if (_showModal) {
      _bottomSheetController = _scaffoldKey.currentState.showBottomSheet(
        (_) => Container(
          height: MediaQuery.of(context).size.height / 4,
          width: MediaQuery.of(context).size.width,
          child: Text('This is a BottomSheet'),
        ),
        backgroundColor: Colors.white,
      );
    } else {
      if (_bottomSheetController != null) _bottomSheetController.close();
      _bottomSheetController = null;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      backgroundColor: Colors.white,
      body: Scaffold(
        bottomNavigationBar: BottomNavigationBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.business),
              label: 'Business',
            ),
          ],
        ),
        body: Center(
          child: ElevatedButton(
            child: Text('Show/Hide Modal Bottom Sheet'),
            onPressed: () => _showOrHide(!_showModal),
          ),
        ),
      ),
    );
  }
}

在这个例子中,我通过使用_scaffoldKey来保留对我的父级ScaffoldState的引用,以便在正确的Scaffold上调用showBottomSheet在DartPad上尝试完整代码 屏幕截图: 进入图像描述 进入图像描述

0
我的解决方法与Guillaume的答案类似。将Scaffold小部件包装在Stack小部件中,使我能够在BottomNavigationBar上放置自定义视图,并在用户进入“导航模式”时设置其显示。
@override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Scaffold(
          body: CupertinoPageScaffold(
            child: IndexedStack(
              index: _selectedPage,
              children: pageList,
            ),
          ),
          bottomNavigationBar: BottomNavigationBar(
            showSelectedLabels: false,
            showUnselectedLabels: false,
            type: BottomNavigationBarType.fixed,
            items: _tabItems(),
            currentIndex: _selectedPage,
            selectedItemColor: DoralColors.darkBlue,
            onTap: _onTabTapped,
          ),
        ),
        if (_navigating == true)
          _navigationView(destination, destinationAddress),
      ],
    );
  }

在上面的代码中,_navigationView 是我自定义的导航视图。最终我选择不使用任何模态视图,因为我无法使其按照我的意愿运作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接