Flutter中的状态管理-GetX插件的使用

平安喜乐

GetX是基于ReactiveX思想的一款响应式状态管理框架,相比于BLoC,它有如下优势:

  • 相比于BLoC,GetX的工程结构更简单,需要维护的文件更少;
  • BLoC无法实现真正的跨页面数据状态管理(全局BLoC可部分实现,但维护起来较麻烦);
  • 内部实现了路由管理,简单易用;

GetX插件的使用

1)在pubspec.yaml中引入getX库,执行flutter pub get;


image.png

2)在Android Studio → Prefrences → Plugins 中搜索 getX,选择并下载插件;


image.png

3)插件下载后,在工程中lib路径下新建 new → flutter bloc,插件会自动生成模版代码;


image.png

输入Module Name后点击OK,自动生成以下文件


image.png

logic层生成的默认代码


image.png

state层生成的默认代码


image.png

view层生成的默认代码


image.png

在GetX范式下,不再通过context传递状态管理器,而是通过put/find获取;

main.dart改造:将原MaterialApp替换为GetMaterialApp,使App能够拥有GetX的特性,GetMaterialApp内部的参数与MaterialApp相同;


image.png

GetX范式下逻辑的编写

需求:点击页面右下角的按钮,每点击一次,页面中间现实的数字+1;

1)UI基础布局


image.png

2)在state中声明需要管理状态的变量,并初始化


image.png

3)在logic中编写相应的计数逻辑,在状态修改后需要手动调用内置函数update()


image.png

4)回到view中,在button的点击事件中调用logic中的方法,并将需要监听状态的组件使用GetBuilder包裹


image.png

以上便完成了在GetX范式下,业务逻辑组件的编写;

GetX也提供了Easy模式,在Easy模式下,将原logic、state合并,整体结构为 logic - view,需要管理状态的变量和对应的逻辑均写在logic中,可用于数据交互简单的页面;

GetX响应式逻辑的编写

GetX也提供了响应式编程的范式,在响应式范式下,相较于标准的GetX范式,我们只需要进行少量的修改;

1)state:用Rx...来定义需要状态管理的的变量的类型,在变量初始化是,加上.obs后缀


image.png

2)logic:直接写状态变换(在这里是增加计数)的逻辑即可,无需调用update()


image.png

3)view:将需要监听状态的组件改用Obx包裹


image.png

以上便完成了GetX下响应式范式的逻辑编写;

GetX标准范式与响应式的对比:

  1. 标准范式是命令式编程,需要手动调用内置函数update();响应式则是配合Rx...变量使用,不需要手动调用其他函数;
  2. 每一个响应式变量都要创建一个GetStream,如果变量较多,或者长数据的场景,对内存消耗较大;
  3. 标准范式采用GetBuilder来包装组件,GetBuilder本质上也是一个Widget,对内存的影响极小;

综上个人推荐使用标准范式;

GetX跨页面交互

相比于BLoC,GetX提供了可以方便的跨页面传递数据的能力,我们先创建两个模块,get_demo_one、get_demo_two;


image.png

需求:页面one支持跳转到页面two,并传递数据到页面two,页面two内部实现点击计数的功能,在退出页面时,将计数同步至页面one;

1)编写get_demo_one_state,声明、初始化需要状态管理的变量


image.png

2)编写get_demo_one_logic,添加count计数和页面跳转的逻辑,Get.to...为GetX中的路由管理函数,在下面会讲到


image.png

3)编写get_demo_one_view的基础UI布局


image.png

4)编写get_demo_two_state,声明、初始化需要状态管理的变量


image.png

5)编写get_demo_two_logic,添加count计数和获取Page One传递过来的数据的逻辑


image.png

6)编写get_demo_two_view的基础UI布局,通过Get.find()函数获取最近一个被初始化的GetDemoOneLogic实例


image.png

以上便完成了GetX范式下,多页面间数据传递的逻辑;

GetX路由管理

简单路由

简单路由就是直接通过Get.to(SomePage())的方式跳转页面,上面例子中PageOne跳转到PageTwo使用的就是简单路由;

命名路由

  • 通过统一配置管理所有页面
  • 通过url方式跳转页面

1)编写配置文件RouteConfig.dart


image.png

2)配置主入口,此处应删掉home参数,因为home和initialRoute会同时初始化,不应该同时设置,这里只保留initialRoute;


image.png

3)使用路由


image.png

4)退出页面:无论使用简单路由,还是命名路由的方式,都是用Get.back()函数来退出当前页面;

GetX资源释放

在使用GetX进行路由管理时,有可能会出现资源未释放的问题;

资源未释放的场景:

  • 使用了GetX范式构建工程,但使用Navigator.push()/Navigator.pop()方式做路由管理;

资源未释放的原因分析:

  • GetxController内部有一套自己的内存管理机制,该机制会通过Get.to()/Get.toName()/Get.back()等方法来触发;
  • 可以理解成,当调用Get.to()/Get.toName()时,GetX会将被导航页面内部创建的GetxController(logic)储存起来,然后再调用Get.back()时,将储存的GetxController(logic)释放掉;
  • 因此,如果使用了Navigator.push()/Navigator.pop()方式做路由管理,GetX无法捕获到当前的GetxController(logic),在页面销毁时自然无法释放掉对应的GetxController(logic);

解决方案:

手动让GetX感知路由,重写页面在感知到push/pop之后的行为;


image.png
  • reportCurrentRoute()方法是将传入的路由交给GetX来管理,继而可以通过GetX来管理路由中的GetxController;
  • reportRouteDispose()方法是通过GetX将传入的路由释放掉;
  • 基于以上修改,即使使用Navigator.push()/Navigator.pop()方式做路由管理的页面,依然可以被GetX获取到GetxController,从而完成资源释放;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容