Flutter:如何在GroupedListView中结合GridView.builder实现分组网格列表
问题
需要基于列表中group字段构建带粘性头部的分组列表,每个分组下方以网格形式展示对应name字段内容。现有代码未正确关联目标数据,无法实现预期效果。
解决方案
步骤1:预处理分组数据
先将原始的groupedData按group字段分组,把同一组的name收集到列表中:
// 预处理分组数据,将同一group的name整合 Map<String, List<String>> get groupedMap { final map = <String, List<String>>{}; for (final item in groupedData) { final group = item['group'] as String; final name = item['name'] as String; map.putIfAbsent(group, () => []).add(name); } return map; }
步骤2:重构列表实现
替换原有依赖组件,直接用ListView.builder结合StickyHeader实现分组粘性头部,同时调整网格展示逻辑:
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:sticky_headers/sticky_headers.dart'; class CombineStickyGrid extends StatefulWidget { const CombineStickyGrid({super.key}); @override State<CombineStickyGrid> createState() => _CombineStickyGridState(); } class _CombineStickyGridState extends State<CombineStickyGrid> { final groupedData = [ {'group': 'Team A', 'name': 'John'}, {'group': 'Team B', 'name': 'Will'}, {'group': 'Team C', 'name': 'Mike'}, {'group': 'Team D', 'name': 'Wayne'}, {'group': 'Team A', 'name': 'Beth'}, {'group': 'Team B', 'name': 'Miranda'}, {'group': 'Team D', 'name': 'Bert'}, {'group': 'Team A', 'name': 'Fred'}, {'group': 'Team A', 'name': 'Bob'}, {'group': 'Team B', 'name': 'Xian'}, {'group': 'Team C', 'name': 'Mi Ping'}, {'group': 'Team D', 'name': 'Olaf'}, {'group': 'Team A', 'name': 'Oscar'}, ]; // 预处理分组数据 Map<String, List<String>> get groupedMap { final map = <String, List<String>>{}; for (final item in groupedData) { final group = item['group'] as String; final name = item['name'] as String; map.putIfAbsent(group, () => []).add(name); } return map; } @override Widget build(BuildContext context) { return ListView.builder( itemCount: groupedMap.keys.length, itemBuilder: (context, index) { final groupName = groupedMap.keys.elementAt(index); final names = groupedMap[groupName]!; return StickyHeader( header: Container( alignment: Alignment.centerLeft, color: Colors.blue, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Text( groupName, style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ), content: GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 5, crossAxisSpacing: 8, mainAxisSpacing: 8, childAspectRatio: 1.2, ), itemCount: names.length, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.all(8), itemBuilder: (context, nameIndex) { return Container( alignment: Alignment.center, color: Colors.grey[100], child: Text( names[nameIndex], textAlign: TextAlign.center, ), ); }, ), ); }, ); } }
关键说明
- 移除了冗余的
simple_grouped_listview依赖,用原生组件组合实现更贴合需求 - 预处理数据时通过
Map聚合同组name,保证分组逻辑清晰 - 给
GridView设置shrinkWrap: true和NeverScrollableScrollPhysics(),避免嵌套滚动冲突 - 微调头部和网格样式,提升视觉可读性
内容的提问来源于stack exchange,提问作者Nivard Herijgers
相关产品推荐
相关产品推荐

