颤振:在/替换底部导航栏上显示模态底部表(无障碍)

Posted

技术标签:

【中文标题】颤振:在/替换底部导航栏上显示模态底部表(无障碍)【英文标题】:Flutter: Show Modal Bottom Sheet over/replacing Bottom Navigation Bar (without barrier) 【发布时间】:2021-05-28 16:58:04 【问题描述】:

我正在尝试为我自己的 Flutter 应用程序复制一些类似于 Google 地图的功能。同样基于地图,我希望用户能够选择兴趣点并可以选择导航到所述位置。

当他们点击“导航”时,我希望底部工作表出现在现有底部导航栏的位置(或顶部),用于基于选项卡的导航。

showModalBottomSheet() 会这样做,但是它有一个屏障阻止用户与父视图交互。我需要它没有障碍。

showBottomSheet() 没有障碍,但也没有放置在底部导航栏的顶部。

是否有一些解决方案才能拥有此功能?我唯一能想到的是将底部导航栏添加到一个容器中,该容器将根据用户是否正在导航来显示/隐藏,但我觉得这是一个相当黑的解决方案,并希望有更优雅的东西。

我在下面附上了几张图片:

第一个屏幕截图显示了具有底部导航栏的 ios 上的 Google 地图标准视图。 第二个屏幕截图显示了“导航前”视图,它是位于底部导航栏顶部(或代替底部导航栏)的底部工作表。这是我试图复制的观点。

【问题讨论】:

你找到什么好的解决方案了吗?我有同样的问题:D 我最终做了类似于 Guillaume 在下面回答的事情。我将包含 BottomNavigationBar 的 Scaffold 包装到 Stack 小部件中,然后在其顶部添加我的自定义导航视图,并将其设置为在用户进入“导航模式”时显示。我已经在下面为您发布了我的代码。 ***.com/a/68208539/1280479 【参考方案1】:

我找到的解决方案是将包含您的bottomNavigationBarScaffold 小部件包装到另一个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

Try the full code on DartPad

截图:

【讨论】:

【参考方案2】:

我解决这个问题的方法类似于纪尧姆的回答。将 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 是我的自定义导航视图。我最终选择不使用任何模态视图,因为我无法让它发挥我想要的作用。

【讨论】:

【参考方案3】:

使用 useRootNavigator: true from showBottomModalSheet

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于颤振:在/替换底部导航栏上显示模态底部表(无障碍)的主要内容,如果未能解决你的问题,请参考以下文章

在底部导航栏上推送新屏幕时出现颤振过渡动画问题

颤振在底部表顶部显示 Snackbar

实现自定义底部选项卡导航器颤振

颤振改变底部导航栏高度

如何单击底部栏上的图标

FloatingActionButton 实现类似 闲鱼 App 底部导航凸起按钮