求Flutter中基于AnimatedContainer展开显示全部Tab的TabBar实现方案及代码
Flutter 展开式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
相关产品推荐
相关产品推荐

