Flutter GetMaterialApp+GetX返回页面时好友列表数据丢失问题求助
问题
我正在学习GetX框架,原本一切正常,但近期发现一个问题:我制作了一个Demo项目,首页为人员列表页面,点击列表项可跳转至详情页面;在详情页中点击按钮可将当前人员添加至好友列表,但当从详情页返回首页后,好友列表的数据会被清空。请问这是什么原因?
详情页代码
class PersonScreen extends StatelessWidget { final Person person; const PersonScreen({Key? key,required this.person}) : super(key: key); @override Widget build(BuildContext context) { PersonController personController=Get.put(PersonController()); return Scaffold( appBar: AppBar( title: Obx(()=>Text(personController.friends.length.toString())), actions: [IconButton(onPressed: (){ }, icon: Icon(Icons.settings))], ), body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children:[ Text(person.name.toString())]), Row( mainAxisAlignment: MainAxisAlignment.center, children:[ IconButton(onPressed: (){ personController.addPerson(person); }, icon: personController.isExist(person)?Icon(Icons.delete):Icon(Icons.add))]), ],), ); } }
Controller代码
class PersonController extends GetxController { List<Person> friends=<Person>[].obs; void addPerson(Person person) { friends.add(person); } bool isExist(Person person) { return friends.contains(person); } }
Main入口代码
return GetMaterialApp( home: HomeScreen(), );
首页代码
class HomeScreen extends StatelessWidget { const HomeScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: ListView.builder( itemCount: persons.length, itemBuilder: (context,index){ Person name=persons[index]; return Padding( padding: EdgeInsets.all(8.0), child: ListTile( onTap: (){ Get.to(PersonScreen(person: name)); }, tileColor: Colors.grey, title: Text(name.name), ), ); }), ); } }
原因分析与解决方案
核心原因
你在详情页PersonScreen的build方法里调用Get.put(PersonController()),每次页面重建时都会创建一个新的Controller实例。当从详情页返回首页后,详情页被销毁,对应的Controller会被GetX自动回收,之前添加的好友数据也随之丢失。同时首页没有获取同一个Controller实例,自然看不到保存的好友数据。
解决方案
1. 全局初始化Controller
在App启动时提前初始化Controller,确保整个生命周期内只有一个实例:
void main() { // 全局注入Controller Get.put(PersonController()); runApp(const MyApp()); }
2. 详情页复用全局Controller
将详情页中的Get.put(PersonController())改为Get.find<PersonController>(),获取已存在的全局实例:
class PersonScreen extends StatelessWidget { final Person person; const PersonScreen({Key? key,required this.person}) : super(key: key); @override Widget build(BuildContext context) { // 获取全局已初始化的Controller PersonController personController = Get.find<PersonController>(); return Scaffold( // 原有代码保持不变 ); } }
3. 可选:首页验证Controller实例
如果担心全局初始化时机问题,也可以在首页的build方法中确保Controller已存在:
class HomeScreen extends StatelessWidget { const HomeScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 检查Controller是否存在,不存在则初始化 Get.find<PersonController>() ?? Get.put(PersonController()); return Scaffold( // 原有代码保持不变 ); } }
内容的提问来源于stack exchange,提问作者user22362195
相关产品推荐
相关产品推荐

