如何在Flutter中实现这种带连线的点式TabBar布局?
实现带连线的点式TabBar布局
一、自定义实现方案
你可以通过Row结合基础组件手动构建这种布局,完全掌控样式细节,核心思路如下:
- 用
Row横向排列所有点与连线 - 区分选中/未选中状态的点样式(大小、颜色)
- 连线部分用
Container实现基础样式,需要动画时可替换为AnimatedContainer或CustomPaint
示例代码
class DottedTabBar extends StatefulWidget { final int itemCount; final int currentIndex; final ValueChanged<int> onTap; final Color selectedColor; final Color unselectedColor; const DottedTabBar({ super.key, required this.itemCount, required this.currentIndex, required this.onTap, this.selectedColor = Colors.blue, this.unselectedColor = Colors.grey, }); @override State<DottedTabBar> createState() => _DottedTabBarState(); } class _DottedTabBarState extends State<DottedTabBar> { @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(widget.itemCount, (index) { return Expanded( child: Column( mainAxisSize: MainAxisSize.min, children: [ GestureDetector( onTap: () => widget.onTap(index), child: Container( width: index == widget.currentIndex ? 20 : 12, height: index == widget.currentIndex ? 20 : 12, decoration: BoxDecoration( color: index == widget.currentIndex ? widget.selectedColor : widget.unselectedColor, shape: BoxShape.circle, ), ), ), // 最后一个点不显示右侧连线 if (index != widget.itemCount - 1) Expanded( child: Container( height: 2, color: index < widget.currentIndex ? widget.selectedColor : widget.unselectedColor, ), ), ], ), ); }), ); } }
使用方式
int _selectedIndex = 0; // 在build方法中调用 DottedTabBar( itemCount: 4, currentIndex: _selectedIndex, onTap: (index) { setState(() { _selectedIndex = index; }); }, )
如果需要过渡动画,把点和连线的Container替换成AnimatedContainer,添加duration参数即可实现平滑切换效果。
二、使用现有Flutter包
如果不想手动写布局,这些现成包可以快速实现需求:
- step_progress_indicator:专门做步骤式进度指示器,支持配置点的大小、连线粗细、颜色,适配TabBar场景
- dots_indicator:原用于轮播指示器,调整参数后也能实现带连线的点式布局
- timeline_tile:适合需要附加标签、图标等复杂样式的场景
以step_progress_indicator为例,基础使用示例:
StepProgressIndicator( totalSteps: 4, currentStep: _selectedIndex + 1, selectedColor: Colors.blue, unselectedColor: Colors.grey, size: 20, padding: const EdgeInsets.symmetric(horizontal: 16), )
使用前需要在pubspec.yaml中添加对应依赖(版本号以官方最新为准)。
内容的提问来源于stack exchange,提问作者Shashank Deepak
相关产品推荐
相关产品推荐

