【问题标题】:Flutter: How to reset TabController index upon bottom navigationFlutter:如何在底部导航时重置 TabController 索引
【发布时间】:2021-02-24 21:07:48
【问题描述】:

我有一个带有 Cupertino 底部导航栏的 Flutter 应用。第一个页面有标签视图like this

我正在努力实现的目标
在离开第一页时(或点击任何底部导航项/图标时),我希望第一页上的选项卡控制器的索引重置为 0,以便当我返回第一页时,我看到默认情况下的初始选项卡(即汽车选项卡)。当前的默认行为是它会显示我离开页面的任何标签。

我如何实现上述目标?我粘贴了下面的示例代码,以在某种程度上复制我的场景。我创建了调用 tabController.previousIndex 的 _resetTabIndex 函数,然后在用户离开页面时尝试调用该函数,但我无法让它工作。提前感谢您对此的任何帮助!

(注意:由于实际应用中的其他要求,我必须坚持使用 Cupertino 底部导航)

ma​​in.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'page1.dart';

void main() {
  runApp(TabBarDemo());
}

class TabBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

enum TabItem { page1, page2 }

class TabItemData {
  const TabItemData({@required this.title, @required this.icon});

  final String title;
  final IconData icon;

  static const Map<TabItem, TabItemData> allTabs = {
    TabItem.page1: TabItemData(title: 'Page 1', icon: Icons.shopping_cart_outlined),
    TabItem.page2: TabItemData(title: 'Page 2', icon: Icons.person_outline_rounded),
  };
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  TabItem _currentTab = TabItem.page1;

  Map<TabItem, WidgetBuilder> get widgetBuilders {
    return {
      TabItem.page1: (_) => Page1(),
      TabItem.page2: (_) => Scaffold(
          appBar: AppBar(
            title: Center(child: Text('Page 2')),
          ),
          body: Center(child: Text('Page 2'))),
    };
  }

  void _resetTabIndex(TabItem tabItem) {
    setState(() => _currentTab = tabItem); // Ignore this. Set up for a behaviour in the complete app.

    // How can I amend this function to trigger the resetTabIndex method in page1.dart (which one alternative I thought might work)?

  }

  @override
  Widget build(BuildContext context) {
    return CupertinoHomeScaffold(
      currentTab: _currentTab,
      onSelectTab: _resetTabIndex,
      widgetBuilders: widgetBuilders,
    );
  }
}

class CupertinoHomeScaffold extends StatelessWidget {
  CupertinoHomeScaffold({
    Key key,
    @required this.currentTab,
    @required this.onSelectTab,
    @required this.widgetBuilders,
  }) : super(key: key);

  final TabItem currentTab;
  final ValueChanged<TabItem> onSelectTab;
  final Map<TabItem, WidgetBuilder> widgetBuilders;

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: [
          _buildItem(TabItem.page1),
          _buildItem(TabItem.page2),
        ],
        onTap: (index) => onSelectTab(TabItem.values[index]),
      ),
      tabBuilder: (context, index) {
        final item = TabItem.values[index];
        return CupertinoTabView(
          builder: (context) => widgetBuilders[item](context),
        );
      },
    );
  }

  BottomNavigationBarItem _buildItem(TabItem tabItem) {
    final itemData = TabItemData.allTabs[tabItem];
    final color = currentTab == tabItem ? Colors.indigo : Colors.grey;
    return BottomNavigationBarItem(
      icon: Icon(itemData.icon, color: color),
      title: Text(
        itemData.title,
        style: TextStyle(color: color),
      ),
    );
  }
}

page1.dart

import 'package:flutter/material.dart';

class Page1 extends StatefulWidget {
  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1> with SingleTickerProviderStateMixin {
  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: 2);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  resetTabIndex() {
    setState(() {
      _tabController.previousIndex;
    });
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _tabController,
          tabs: [
            Tab(icon: Icon(Icons.directions_car)),
            Tab(icon: Icon(Icons.directions_bike)),
          ],
        ),
        title: Center(child: Text('Page 1')),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          Icon(Icons.directions_car),
          Icon(Icons.directions_bike),
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: flutter dart flutter-layout


    【解决方案1】:

    离开第一页时,请执行此操作 _tabController.animateTo(0,duration: Duration(milliseconds: 200),curve:Curves.easeIn);

    【讨论】:

    • 感谢您的回复。我是 Flutter 的新手,所以不确定我将把这段代码放在哪里?例如,如果我将它添加到page1.dart 中的resetTabIndex 函数中,main.dart 中的底部导航如何触发该函数?
    • @Camron 您可以在从一个页面导航到另一个页面的位置添加它。我认为那是你的 _resetTabIndex 函数,所以里面会做
    猜你喜欢
    • 2020-07-18
    • 2018-10-04
    • 2019-02-18
    • 2020-02-07
    • 1970-01-01
    • 2021-01-01
    • 2020-12-17
    • 2020-11-13
    相关资源
    最近更新 更多