颤动底部导航,其中一页有标签

Posted

技术标签:

【中文标题】颤动底部导航,其中一页有标签【英文标题】:Flutter bottom navigation where one page has tabs 【发布时间】:2019-07-06 15:48:28 【问题描述】:

我想创建一个带有底部导航栏的脚手架,以及一个始终显示当前页面标题的应用栏。当我更改底栏选项时,内容会发生明显变化。到目前为止,经典的 NavigationBar 结构一切正常。但是当内容页面的顶部应该有标签时,问题就开始了。我在父母 Scaffold 中创建了我的 appbar。无论如何要向父小部件 appBar 添加标签?

我的 AppBar + BottomNavBar 页面:

class MainPage extends StatefulWidget 
  @override
  State<StatefulWidget> createState() 
    return _MainPageState();
  

class _MainPageState extends State<MainPage> 

  int _currentPageIndex;
  List<Widget> _pages = List();

  Widget _getCurrentPage() => _pages[_currentPageIndex];

  @override
  void initState() 
    setState(() 
      _currentPageIndex = 0;

      _pages.add(BlocProvider(bloc: AgendaBloc(), child: AgendaPage()));
      _pages.add(SpeakersPage());
      _pages.add(MenuPage());
    );
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: MyAppBar( title: 'Agenda'),
      body: _getCurrentPage(),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentPageIndex,
        onTap: (index)
          setState(() 
            _currentPageIndex = index;
          );
        ,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.content_paste),
            title: Text('Agenda'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.group),
            title: Text('Speakers'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.menu),
            title: Text('Menu'),
          ),
        ],
      ),
    );
  

现在假设我希望我的 AgendaPage 小部件在视图顶部显示选项卡。有没有什么简单的方法可以做到这一点?

想要的效果:

【问题讨论】:

同时使用标签和底部导航听起来像笨拙的 UI。这样做的目的是什么? 我将编辑并添加屏幕截图以获取更多上下文。 我正在努力实现这一点,您是否可以放置您的代码解决方案? 我现在无法访问此代码。你基本上是在 Alexanders 的回答中做的,“_getCurrentPage()”方法返回你的小部件,它应该被包裹在另一个 Scaffold 中。但是这次这个 Scaffold 可以包含以标准方式制作的选项卡,可以在任何教程中找到。如果您仍然遇到问题,请随时询问。 【参考方案1】:

据我所知,您不能,但我设法通过在通过bottomNavigationBar 导航的每个页面添加单独的AppBar 来解决此问题:

为您的每个_pages 提供一个单独的应用栏,并从您的build 方法中删除主要的。

【讨论】:

这就是我设法做到的。从“app-bar-only-page”到另一个的过渡很顺利。但是,当切换到带有标签的页面时,会出现“丑陋”的重绘(应用栏闪烁一秒钟)。想可能有什么我可以做的,只是还不知道。 如果您希望应用栏缩小,请查看sliverAppbar【参考方案2】:

您可以使用嵌套的Scaffold 小部件。这适用于 Flutter 1.1.8:

// This is the outer Scaffold. No AppBar here
Scaffold(
  // Workaround for https://github.com/flutter/flutter/issues/7036
  resizeToAvoidBottomPadding: false, 
  body: _getCurrentPage(),  // AppBar comes from the Scaffold of the current page 
  bottomNavigationBar: BottomNavigationBar(
    // ...
  )
)

【讨论】:

将此答案标记为正确,因为这是我最终要做的。似乎运作良好。以防有人犯了我的错误:如果您使用 StreamBuilder 构建选项卡页面,请注意它总是会发出 null 作为第一个元素。这可能会导致抖动呈现您的“无数据视图”(可能是空容器),然后呈现正确的视图。效果是每次切换到它们时选项卡都会“闪烁”。

以上是关于颤动底部导航,其中一页有标签的主要内容,如果未能解决你的问题,请参考以下文章

使用底部应用栏标签导航 - 颤动

使用底部导航栏颤动保存 PageView 内每个页面的状态

使用底部导航栏导航回页面时颤动通过底部导航栏选择的索引

移动到其他页面时无法保持底部导航栏颤动

如何使用颤动的底部导航栏导航到几个新页面?

如何将底部导航栏添加到此颤动代码