Flutter实现添加数据后无需重启应用更新ListView
解决Flutter SQLite添加数据后ListView不自动更新的问题
问题根源
首页的FutureBuilder仅在初始化时执行一次getStudentDetails()获取数据,添加新数据后没有触发重新查询,因此ListView不会自动刷新。
解决方案1:页面返回触发刷新(简单易实现)
步骤1:修改首页代码
在首页的State类中做如下调整:
- 定义变量存储学生列表的Future:
late Future<List<Student>> _studentFuture;
- 在
initState中初始化该Future:
@override void initState() { super.initState(); _studentFuture = DatabaseHelper.instance.getStudentDetails(); }
- 添加刷新列表的方法:
void _refreshStudentList() { setState(() { // 重新获取数据,触发FutureBuilder重建 _studentFuture = DatabaseHelper.instance.getStudentDetails(); }); }
- 修改
FutureBuilder的future参数为定义的变量:
FutureBuilder<List<Student>>( future: _studentFuture, // 替换原直接调用的方法 builder: (context, snapshot) { // 原有builder逻辑保持不变 }, )
- 修正长按删除的逻辑,删除后调用刷新方法:
onLongPress: () async { await DatabaseHelper.instance.remove(student.id!); _refreshStudentList(); // 刷新列表 },
- 修改跳转至添加页面的代码,返回后触发刷新:
// 假设跳转方式为Navigator.push Navigator.push( context, MaterialPageRoute(builder: (_) => AddStudentPage()), ).then((_) { // 从添加页面返回后刷新列表 _refreshStudentList(); });
步骤2:修改添加页面的保存按钮
保存数据后直接返回首页,无需在添加页面调用setState:
floatingActionButton: FloatingActionButton( child: Icon(Icons.save), onPressed: () async { await DatabaseHelper.instance.add( Student(name: nameController.text, course: courseController.text), ); nameController.clear(); courseController.clear(); selectedId = null; // 返回首页 Navigator.pop(context); }, ),
解决方案2:用StreamBuilder实现自动监听(更优雅)
若希望数据变化时自动更新,可将FutureBuilder替换为StreamBuilder,让数据库操作返回数据流:
- 修改
DatabaseHelper类,添加数据流监听:
class DatabaseHelper { // 原有单例、数据库初始化代码保持不变 final _studentStreamController = StreamController<List<Student>>.broadcast(); // 初始化时发送初始数据 void _initStream() async { _studentStreamController.add(await getStudentDetails()); } // 获取学生列表的数据流 Stream<List<Student>> getStudentStream() { if (!_studentStreamController.hasListener) { _initStream(); } return _studentStreamController.stream; } // 添加数据后更新数据流 Future<int> add(Student student) async { final db = await database; final id = await db.insert(tableStudents, student.toMap()); // 推送新数据到数据流 _studentStreamController.add(await getStudentDetails()); return id; } // 删除数据后更新数据流 Future<int> remove(int id) async { final db = await database; final count = await db.delete(tableStudents, where: 'id = ?', whereArgs: [id]); // 推送新数据到数据流 _studentStreamController.add(await getStudentDetails()); return count; } // 页面销毁时关闭控制器,避免内存泄漏 void dispose() { _studentStreamController.close(); } }
- 首页替换为
StreamBuilder:
StreamBuilder<List<Student>>( stream: DatabaseHelper.instance.getStudentStream(), builder: (context, snapshot) { if (!snapshot.hasData) { return Center(child: Text('Loading...')); } return snapshot.data!.isEmpty ? Center(child: Text('No Student Details in List.')) : ListView( children: snapshot.data!.map((student) { return Center( child: Card( color: selectedId == student.id ? Colors.white70 : Colors.white, child: ListTile( title: Text('Student Name : ${student.name}'), subtitle: Text('Course : ${student.course}'), onTap: () {}, onLongPress: () { DatabaseHelper.instance.remove(student.id!); }, ), ), ); }).toList(), ); }, )
这样添加或删除数据后,数据流会自动推送新数据,ListView将自动刷新,无需手动调用刷新方法。
内容的提问来源于stack exchange,提问作者sameera
相关产品推荐
相关产品推荐

