受到在做 Android 开发时 MVVM 架构的影响,在开发 Flutter 项目时,在架构实际上我都会有意的向 MVVM 方向上靠。所幸 dart 语言的语法有点像 Java 和 Kotlin 的结合体,所以架构上除了 View 层,其它层都非常的相似。
需求
有个带搜索框的列表页面,数据从本地数据库中加载而来,列表页面中还有个Add
按钮,点击按钮后跳转到一个新页面,新页面可以添加新的数据。当新数据添加完成后返回到列表页面,列表页面需要把符合条件的新数据加载出来。
思路:
- 数据库的框架有接口对当前数据添加一个观察者,当有数据变动时就触发之前的加载逻辑。
- Hive 框架中的 Box 有个
watch()
方法,它返回一个 Stream 类型的数据,用于监听单个数据或者所有数据的变动(取决于是否传递单个数据的 key)。
解决方案
跟 floor 框架 Dao 里声明的 Stream 的方法一样,当数据发生变化时,会自动更新。
Hive 版的解决方案如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import 'package:hive/hive.dart';
@override Stream<List<Note>> getAllNotes(String userId) { return Stream.fromFuture(_getCachedBox()).flatMap((innerBox) => _watchNotes(innerBox)); }
@override Stream<List<Note>> searchNotes(String userId, String searchKey) { return Stream.fromFuture(_getCachedBox()).flatMap((innerBox) => _watchNotes(innerBox, filter: searchKey)); }
Stream<List<Note>> _watchNotes(Box<Note> noteBox, {String filter = ''}) { return noteBox.watch().map((event) => _getAllStoreNotes(noteBox, filter)).startWith(_getAllStoreNotes(noteBox, filter)); }
List<Note> _getAllStoreNotes(Box<Note> noteBox, String filter) { List<Note> noteList = noteBox.values.where((note) => filter == '' || note.title?.contains(filter) == true).toList(); noteList.sort((a, b) { return a.title?.compareTo(b.title ?? '') ?? 0; }); return noteList; }
|
这样列表页面的数据重新加载就取决于当前数据是否真的有变动。