You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Tab Bar点击切换页面失效问题求助

自定义TabBar页面切换问题修复方案

问题分析

你的代码存在几个核心问题:

  1. TabBar的tabs使用错误:TabBar的tabs属性需要接收Tab组件列表,而你直接嵌套了ListView.builder,不符合TabBar的用法规范,导致TabController无法正确关联每个标签。
  2. 自定义选中状态与TabController未同步:你用自己维护的_isSelectedIndex控制标签样式,但没和_tabController的索引绑定,点击标签时只更新了本地状态,没通知TabController切换,所以TabBarView不会跟着变化。
  3. 横向滚动实现方式错误:TabBar本身支持横向滚动(设置isScrollable: true即可),不需要嵌套ListView来实现。

修复后的完整代码

class MyTabBar extends StatefulWidget {
  const MyTabBar({Key? key}) : super(key: key);

  @override
  State<MyTabBar> createState() => _MyTabBarState();
}

class _MyTabBarState extends State<MyTabBar> with SingleTickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: tabBarItems.length);
    // 监听TabController索引变化,同步更新UI
    _tabController.addListener(() {
      if (_tabController.indexIsChanging) {
        setState(() {});
      }
    });
  }

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

  List<Widget> pageList = [
    const AllShoesPage(),
    const JordanPage(),
    const BasketBallPage(),
    const TennisPage(),
    const WalkingPage(),
    const SoccerPage()
  ];

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(
          height: 60.0,
          width: double.infinity,
          child: TabBar(
            controller: _tabController,
            isScrollable: true, // 开启横向滚动
            indicator: const BoxDecoration(), // 隐藏默认指示器
            tabs: List.generate(tabBarItems.length, (index) {
              return Column(
                children: [
                  Container(
                    margin: const EdgeInsets.all(5.0),
                    height: 45,
                    width: MediaQuery.of(context).size.width / 5,
                    decoration: BoxDecoration(
                      color: _tabController.index == index
                          ? Appcolors.primaryColor
                          : Appcolors.whiteColor,
                      borderRadius: BorderRadius.circular(10.0),
                    ),
                    child: Center(
                      child: Text(
                        tabBarItems[index],
                        style: GoogleFonts.poppins(
                          color: _tabController.index == index
                              ? Appcolors.whiteColor
                              : Appcolors.darkGreyColor,
                        ),
                      ),
                    ),
                  ),
                  Visibility(
                    visible: _tabController.index == index,
                    child: Container(
                      width: 5,
                      height: 5,
                      decoration: const BoxDecoration(
                        color: Appcolors.primaryColor,
                        shape: BoxShape.circle,
                      ),
                    ),
                  )
                ],
              );
            }),
          ),
        ),
        Expanded( // 让TabBarView占据剩余空间,修复高度异常
          child: TabBarView(
            controller: _tabController,
            children: pageList,
          ),
        )
      ],
    );
  }
}

关键修复点说明

  • 移除ListView嵌套:用List.generate生成Tab列表,配合isScrollable: true实现横向滚动,符合TabBar标准用法。
  • 同步TabController与UI状态:删除自定义的_isSelectedIndex,直接用_tabController.index判断选中项,通过addListener监听索引变化触发UI更新。
  • 修复TabBarView高度:用Expanded包裹TabBarView,避免高度为0的问题。
  • 替换默认指示器:隐藏TabBar自带下划线,保留你自定义的圆形选中指示器。

内容的提问来源于stack exchange,提问作者Martins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:05:30