Flutter中如何用ExpansionTile和ListView展示SQLite数据
问题解决思路与实现方案
一、_getData调用的常见问题排查
- 若在
initState中调用_getData,必须在数据获取完成后通过setState更新UI——SQLite操作是异步的,不触发状态更新的话UI不会刷新 - 绝对不能在
build方法里直接调用_getData,这会导致每次组件重建都重复查询数据库,引发无限循环
二、核心实现步骤
1. 数据库查询逻辑调整
在DBHelper中实现全量教师数据查询(后续在内存中分组,比多次查询更高效):
// DBHelper类中的方法 Future<List<Map<String, dynamic>>> getAllTeachers() async { Database db = await this.database; return await db.query('teachers'); }
2. 数据分组与Fields类映射
在_getData方法中,将查询结果按section分组,再转成Fields类的列表:
// 假设你的Fields类结构如下 class Fields { final String section; final List<String> dataList; Fields(this.section, this.dataList); } List<Fields> _sectionTeachers = []; Future<void> _getData() async { List<Map<String, dynamic>> rawTeachers = await DBHelper().getAllTeachers(); // 按section分组存储教师姓名 Map<String, List<String>> groupedData = {}; for (var teacher in rawTeachers) { String section = teacher['section'] as String; String name = teacher['name'] as String; groupedData.putIfAbsent(section, () => []); groupedData[section]!.add(name); } // 转换为Fields列表并更新状态 setState(() { _sectionTeachers = groupedData.entries.map((entry) { return Fields(entry.key, entry.value); }).toList(); }); }
3. ExpansionTile + ListView展示数据
在build方法中遍历分组后的列表,生成对应的展开项:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('教师数据')), body: ListView.builder( itemCount: _sectionTeachers.length, itemBuilder: (context, index) { Fields currentSection = _sectionTeachers[index]; return ExpansionTile( title: Text(currentSection.section), children: [ ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: currentSection.dataList.length, itemBuilder: (context, idx) { return ListTile(title: Text(currentSection.dataList[idx])); }, ) ], ); }, ), ); }
三、关键注意事项
- 在
initState中初始化调用_getData:
@override void initState() { super.initState(); _getData(); }
- 内层ListView必须设置
shrinkWrap: true和NeverScrollableScrollPhysics,避免嵌套滚动冲突 - 若数据库数据量大,可考虑在DBHelper中直接执行分组查询(如
SELECT section, GROUP_CONCAT(name) FROM teachers GROUP BY section),减少内存处理压力
内容的提问来源于stack exchange,提问作者PLAA Hemantha
相关产品推荐
相关产品推荐

