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

求Flutter中基于AnimatedContainer展开显示全部Tab的TabBar实现方案及代码

Flutter 展开式TabBar实现方案

展开式TabBar效果

Flutter官方没有直接提供这种展开式TabBar的现成组件,但可以通过组合AnimatedContainer、TabBar和自定义交互逻辑实现。以下是满足你需求的完整实现代码:

import 'package:flutter/material.dart';

class ExpandableTabBar extends StatefulWidget {
  final List<Tab> tabs;
  final Widget Function(int) tabViewBuilder;

  const ExpandableTabBar({
    super.key,
    required this.tabs,
    required this.tabViewBuilder,
  });

  @override
  State<ExpandableTabBar> createState() => _ExpandableTabBarState();
}

class _ExpandableTabBarState extends State<ExpandableTabBar> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  bool _isExpanded = false;
  double _tabBarHeight = 48.0;
  final double _collapsedHeight = 48.0;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: widget.tabs.length, vsync: this);
    // 根据Tab数量计算展开后的高度,这里按两行示例
    _tabBarHeight = widget.tabs.length > 4 ? 96.0 : _collapsedHeight;
  }

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

  void _toggleExpand() {
    setState(() {
      _isExpanded = !_isExpanded;
      _tabBarHeight = _isExpanded 
          ? (widget.tabs.length > 4 ? 96.0 : _collapsedHeight)
          : _collapsedHeight;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        AnimatedContainer(
          duration: const Duration(milliseconds: 300),
          curve: Curves.easeInOut,
          height: _tabBarHeight,
          child: Column(
            children: [
              TabBar(
                controller: _tabController,
                isScrollable: !_isExpanded,
                tabs: widget.tabs.take(4).toList(),
                indicatorColor: Colors.blue,
                labelColor: Colors.blue,
                unselectedLabelColor: Colors.grey,
              ),
              if (_isExpanded)
                TabBar(
                  controller: _tabController,
                  isScrollable: false,
                  tabs: widget.tabs.skip(4).toList(),
                  indicatorColor: Colors.blue,
                  labelColor: Colors.blue,
                  unselectedLabelColor: Colors.grey,
                ),
            ],
          ),
        ),
        IconButton(
          icon: Icon(_isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down),
          onPressed: _toggleExpand,
        ),
        Expanded(
          child: TabBarView(
            controller: _tabController,
            children: List.generate(widget.tabs.length, (index) => widget.tabViewBuilder(index)),
          ),
        ),
      ],
    );
  }
}

// 使用示例
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("展开式TabBar示例")),
        body: ExpandableTabBar(
          tabs: const [
            Tab(text: "Tab 1"),
            Tab(text: "Tab 2"),
            Tab(text: "Tab 3"),
            Tab(text: "Tab 4"),
            Tab(text: "Tab 5"),
            Tab(text: "Tab 6"),
            Tab(text: "Tab 7"),
          ],
          tabViewBuilder: (index) {
            return Center(child: Text("内容 ${index + 1}"));
          },
        ),
      ),
    );
  }
}

代码说明:

  • 用AnimatedContainer实现TabBar区域的高度平滑过渡动画
  • 收起状态下TabBar设为可滚动,仅显示前4个Tab;展开状态下分多行显示全部Tab
  • 通过图标按钮触发展开/收起的状态切换
  • 借助TabController同步TabBar和TabBarView的选中状态

你可以根据实际需求调整:

  • 收起时显示的Tab数量
  • 展开后的Tab排列行数
  • 动画时长、曲线等参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:55:59