Flutter中实现可折叠Chip布局:空间不足时隐藏Chip并显示数量
Flutter 实现可折叠 Chip 布局(空间不足时自动折叠多余 Chip)
一、第三方库方案(更推荐,省得自己造轮子)
直接用成熟的第三方库能快速搞定需求,给你两个靠谱的选项:
1. collapsible_chips 库
这个库专门针对这类场景做了优化,空间不足时自动将放不下的 Chip 折叠成带计数的 Chip,用法简单:
- 先在
pubspec.yaml中添加依赖:dependencies: collapsible_chips: ^最新版本号 # 可去 pub.dev 查询最新版本 - 示例代码:
CollapsibleChips( chips: [ Chip(label: Text('标签1')), Chip(label: Text('标签2')), Chip(label: Text('标签3')), // 可添加任意数量的 Chip ], collapsedChipBuilder: (remainingCount) { return Chip(label: Text('+$remainingCount')); }, )
2. flutter_flow_chips 库
这个库除了基础折叠功能,还支持点击展开折叠的 Chip,交互性更强:
- 添加依赖:
dependencies: flutter_flow_chips: ^最新版本号 - 核心用法:
FlowChipList( chips: [ FlowChip(label: Text('Flutter')), FlowChip(label: Text('Dart')), FlowChip(label: Text('iOS')), FlowChip(label: Text('Android')), ], onTap: (tappedChip) { /* 可添加Chip点击逻辑 */ }, collapsedText: '+${remainingCount}', )
二、自定义实现(不想依赖第三方库的话)
如果不想用外部库,自己通过 LayoutBuilder 结合 Wrap 也能实现,核心思路是先计算可用空间能容纳的 Chip 数量,剩余数量用计数 Chip 代替:
示例代码片段:
class CollapsibleChipRow extends StatefulWidget { final List<Chip> chips; const CollapsibleChipRow({super.key, required this.chips}); @override State<CollapsibleChipRow> createState() => _CollapsibleChipRowState(); } class _CollapsibleChipRowState extends State<CollapsibleChipRow> { int _visibleCount = 0; int _remainingCount = 0; @override void didChangeDependencies() { super.didChangeDependencies(); _calcVisibleChips(); } void _calcVisibleChips() { final renderBox = context.findRenderObject() as RenderBox; final availableWidth = renderBox.size.width; double totalWidth = 0; int count = 0; for (var chip in widget.chips) { // 计算Chip宽度+间距,间距可根据需求调整 final chipWidth = chip.preferredSize.width + 8; if (totalWidth + chipWidth <= availableWidth) { totalWidth += chipWidth; count++; } else { break; } } setState(() { _visibleCount = count; _remainingCount = widget.chips.length - count; }); } @override Widget build(BuildContext context) { final visibleChips = widget.chips.take(_visibleCount).toList(); if (_remainingCount > 0) { visibleChips.add(Chip(label: Text('+$_remainingCount'))); } return Wrap( spacing: 8, runSpacing: 8, children: visibleChips, ); } }
注意:这是基础实现,实际使用时可根据需求调整间距计算、适配不同屏幕尺寸,或添加展开/收起的交互逻辑。
内容的提问来源于stack exchange,提问作者Bitlejuce Do
相关产品推荐
相关产品推荐

