Flutter中如何用GetX实现模型数据传递及列表同步更新?
解决方案
核心思路
利用GetX的响应式特性,让列表数据源和模型具备可观察性,修改模型数据时自动同步到原列表,无需手动触发刷新。
方案一:模型字段改为Rx类型(推荐,细粒度控制)
1. 改造模型类
将需要修改的字段改为Rx类型,确保字段变化能被监听:
class QAEntity { var title = ''.obs; var content = ''.obs; // 其他业务字段同理改为Rx类型 }
2. 列表控制器定义RxList数据源
class FindQAController extends GetxController { // 定义可观察列表 var listData = <QAEntity>[].obs; var hasMore = true.obs; // 刷新数据示例 void refreshData() async { // 模拟接口请求获取数据 List<QAEntity> newData = await fetchQAList(); // 替换列表数据(会触发UI刷新) listData.assignAll(newData); } // 加载更多示例 void loadMore() async { if (!hasMore.value) return; List<QAEntity> moreData = await fetchQAMore(); if (moreData.isEmpty) { hasMore.value = false; } else { listData.addAll(moreData); } } }
3. 列表页传递模型引用
列表项用Obx包裹,监听模型字段变化自动更新UI:
class FindItemQAPage extends StatelessWidget { final QAEntity entity; const FindItemQAPage(this.entity, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Obx(() => ListTile( title: Text(entity.title.value), subtitle: Text(entity.content.value), onTap: () { // 跳转详情页并传递模型引用 Get.to(() => FindQADetailPage(), arguments: entity); }, )); } }
4. 详情页修改模型数据
直接操作传递过来的模型的Rx字段,修改后自动同步回原列表:
class FindQADetailPage extends StatelessWidget { const FindQADetailPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 获取传递的模型引用 QAEntity entity = Get.arguments as QAEntity; return Scaffold( appBar: AppBar(title: const Text('修改问答')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( decoration: const InputDecoration(labelText: '标题'), controller: TextEditingController(text: entity.title.value), onChanged: (value) { // 直接修改Rx字段,自动同步 entity.title.value = value; }, ), const SizedBox(height: 16), TextField( decoration: const InputDecoration(labelText: '内容'), controller: TextEditingController(text: entity.content.value), onChanged: (value) { entity.content.value = value; }, ), ], ), ), ); } }
方案二:整个模型转为Rx对象(适合已有模型类无需修改字段)
如果不想改动原模型类的字段结构,可以将整个模型包装为Rx对象:
1. 原模型类保持不变
class QAEntity { String title; String content; QAEntity({required this.title, required this.content}); }
2. 列表控制器定义RxList<Rx>
class FindQAController extends GetxController { var listData = <Rx<QAEntity>>[].obs; var hasMore = true.obs; void refreshData() async { List<QAEntity> newData = await fetchQAList(); // 将每个模型转为Rx对象后添加到列表 listData.assignAll(newData.map((e) => e.obs).toList()); } }
3. 列表页传递Rx模型
class FindItemQAPage extends StatelessWidget { final Rx<QAEntity> entity; const FindItemQAPage(this.entity, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Obx(() => ListTile( title: Text(entity.value.title), subtitle: Text(entity.value.content), onTap: () => Get.to(() => FindQADetailPage(), arguments: entity), )); } }
4. 详情页修改模型
使用update方法更新整个模型:
class FindQADetailPage extends StatelessWidget { const FindQADetailPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { Rx<QAEntity> entity = Get.arguments as Rx<QAEntity>; return Scaffold( appBar: AppBar(title: const Text('修改问答')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( decoration: const InputDecoration(labelText: '标题'), controller: TextEditingController(text: entity.value.title), onChanged: (value) { entity.update((val) { val?.title = value; }); }, ), const SizedBox(height: 16), TextField( decoration: const InputDecoration(labelText: '内容'), controller: TextEditingController(text: entity.value.content), onChanged: (value) { entity.update((val) { val?.content = value; }); }, ), ], ), ), ); } }
注意事项
- 列表页的
DeerListView必须包裹在Obx中,确保列表数据源变化时刷新UI - 必须传递模型引用而非副本,才能实现数据同步
- 若需复杂业务逻辑,可在详情页控制器中持有模型引用,通过控制器方法修改数据
内容的提问来源于stack exchange,提问作者Madlife.zyc
相关产品推荐
相关产品推荐

