每次当前选项卡在 TabBar 颤动中更改时,如何将新页面添加到导航器堆栈?

Posted

技术标签:

【中文标题】每次当前选项卡在 TabBar 颤动中更改时,如何将新页面添加到导航器堆栈?【英文标题】:How to add a new page to navigator stack each time the current tab changes in a TabBar flutter? 【发布时间】:2020-06-23 00:00:57 【问题描述】:

我是 Flutter 的新手,我正在尝试克隆 instagram。我已经在线检查了如何实现bottomNavigator 并使其在每个屏幕上都可见,并且所有这些都使用TabView 和TabBar 指向我。它工作正常,但是当我更改为新选项卡时,它不会被添加到导航堆栈中。因此,当我单击移动返回按钮时,它会关闭应用程序,因为堆栈中没有要弹出的项目。下面是标签导航器的示例代码。

class TabBarDemo extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.directions_car)),
                Tab(icon: Icon(Icons.directions_transit)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
            title: Text('Tabs Demo'),
          ),
          body: TabBarView(
            children: [
              Icon(Icons.directions_car),
              Icon(Icons.directions_transit),
              Icon(Icons.directions_bike),
            ],
          ),
        ),
      ),
    );
  

如何更改此代码,以便每次更改选项卡时,它都按现在的方式工作,但新选项卡应推送到导航堆栈。这样我就可以点击设备后退按钮,它会将我带回到 tab1 而不会关闭应用程序。

我希望导航能够正常工作,并且感觉就像 instagram 在 Android 上的工作方式一样。

【问题讨论】:

【参考方案1】:

基本的底部导航栏来源: BottomNavigationBar

int _selectedIndex = 0;
static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
  Text(
    'Index 0: Home',
    style: optionStyle,
  ),
  Text(
     'Index 1: Business',
     style: optionStyle,
  ),
  Text(
     'Index 2: School',
     style: optionStyle,
  ),
];

void _onItemTapped(int index) 
  setState(() 
    _selectedIndex = index;
  );


@override
Widget build(BuildContext context) 
  return Scaffold(
    appBar: AppBar(
      title: const Text('BottomNavigationBar Sample'),
    ),
    body: Center(
      // This is where the content is changing and 
      // you can have it visible on every screen
      child: _widgetOptions.elementAt(_selectedIndex),
    ),
    bottomNavigationBar: BottomNavigationBar(
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          title: Text('Home'),
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.business),
          title: Text('Business'),
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.school),
          title: Text('School'),
        ),
      ],
      currentIndex: _selectedIndex,
      selectedItemColor: Colors.amber[800],
      onTap: _onItemTapped,
    ),
  );

对于推送和弹出逻辑,您需要使用Navigator 并提供自己的onGenerateRoute,而不是使用_widgetOptions 列表。你可以在这里了解它Navigator。它会变成这样:

@override
Widget build(BuildContext context) 
  return Scaffold(
    appBar: AppBar(
      title: const Text('BottomNavigationBar Sample'),
    ),
    body: Navigator(
      key: ..,
      initialRoute: ..,
      onGenerateRoute: ..,
    ),
    bottomNavigationBar: BottomNavigationBar(
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          title: Text('Home'),
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.business),
          title: Text('Business'),
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.school),
          title: Text('School'),
        ),
      ],
      currentIndex: _selectedIndex,
      selectedItemColor: Colors.amber[800],
      onTap: ..,
    ),
  );

这里解释起来有点复杂,所以我只是给你一些参考如何实现onGenerateRoute

    一个很棒的包叫auto_route 制作自己的onGenerateRoute clean-navigation-in-flutter-using-generated-routes

【讨论】:

以上是关于每次当前选项卡在 TabBar 颤动中更改时,如何将新页面添加到导航器堆栈?的主要内容,如果未能解决你的问题,请参考以下文章

当新页面被推入颤动时如何隐藏本机Tabbar?

垂直窗口 TabBar 菜单和颤动中的动画指示器

在运行时更改 TabBar 中的选项卡

如何在颤动中更改文本按钮颜色?

颤动底部导航,其中一个页面有选项卡

如何在颤动中推动替换删除整个导航堆栈?