准备
引入
getx 状态管理框架 https://pub.flutter-io.cn/packages/get
非空安全最后一个版本(flutter 2.0之前版本)
get: ^3.26.0
空安全版本 最新版本请查看 https://pub.flutter-io.cn/packages/get
get: ^4.1.3
GetX地点
- Github:jonataslaw/getx
- Pub:get
主入口配置
- 只须要将MaterialApp改成GetMaterialApp即可
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
home: CounterGetPage(),
);
}
}
import ‘package:get/get.dart’;
插件
吐槽下写插件的过程,实际写这种模板代码生成插件,其实也不难,网上有很多人写了范例,参考参考思路,能较快的整出来,就是有些配置比较蛋筒。
一开始选择Plugin DevKit模式整的,都已经写好,但是看官网文档的时候,官方文档开头就说了:建议使用Gradle模式开发插件,又巴拉巴拉列了一堆利益;考虑很久,决定用Gradle模式重写。
这个Gradle模式,最烦的还是开头新建项目的时候,谁人Gradle死活下载不下来,科学全局上网都不行,然后手动下载了Gradle,指定本地Gradle,开全局再次同步时,会下载一个较大的社区版IDEA,但是使用本地Gradle加载完,存在一个很大的BUG!main文件夹下,不会自动生成Java文件夹!我真是佛了,点击别的的文件夹,右击:New -> Plugin DevKit 居然不会没有Action选项,差点把我劝退了,换了了七八个版本IDEA试了都不行!Action选项出不来,过了俩天后,晚上无意尝试在main文件夹下面新建了一个Java文件,然后在这个java文件上右击:New -> Plugin DevKit,Action选项出现了!真几把佛了。。。
另有个巨坑的题目,在Gradle模式下开发插件,把模板代码文件放在main文件下、放在src下、放在根目次下,都获取不到文件里面的内容,这个真是坑了我不少时间,搜了很多博客,都发现没写这个题目,官方文档范例看了几遍也没发现有啥阐明,后来找到了一个三年前的项目,翻了翻代码发现,所有的资源文件都必须放在resources文件夹下,才能读取到文件内容。。。我勒个去。。。
阐明
- 插件地点
- Github:getx_template
- Jetbrains:getx_template
- 插件效果
- 看下插件使用的效果图吧,样式参考了fish_redux插件样式
- 有一些可选择的功能,所以做成多按钮的样式,大家可以按照自己的需求举行利用
- 说下插件的功能含义
- Model:生成GetX的模式,
- Default:默认模式,生成三个文件:state,logic,view
- Easy:简单模式,生成俩个文件:logic,view
- Function:功能选择
- useFolder:使用文件,选择后会生成文件夹,大驼峰命名自动转换为:小写+下划线
- usePrefix:使用前缀,生成的文件前加上前缀,前缀为:大驼峰命名自动转换为:小写+下划线
- Module Name:模块的名称,请使用大驼峰命名
效果图
[外链图片转存中…(img-RphXgC4a-1734683976536)]
[外链图片转存中…(img-BTDmNkHw-1734683976539)]
- Alt + Enter : 可以选择包裹Widget,有三种可选(GetBuilder、Obx、GetX),大大方便开发哟(^U^)ノ~YO
[外链图片转存中…(img-ob1BnizY-1734683976539)]
- 快捷代码片断提示:我自己写了俩个,别的的快捷代码来自:getx-snippets-intelliJ
- 输入 get 前缀便有提示
[外链图片转存中…(img-8e78MWRF-1734683976539)]
安装
- 在设置里面选择:Plugins —> 输入“getx”搜刮 —> 选择名字为:“GeX” —> 然后安装 —> 最后记得点击下“Apply”
- 如果在使用该插件的过程中有什么题目,请在该项目的github上给我提issue,我看到后,会尽快处理
[外链图片转存中…(img-sU1S5H5e-1734683976539)]
资源释放
关于GetxController的资源释放,这个栏目的内容,我必须把它放在前面阐明下,这个模块内容相当紧张!
资源未释放的场景
在我们使用GetX的时候,可能没什么GetxController未被释放的感觉,这种环境,是由于我们一般都是用了getx的那一套路由跳转api(Get.to、Get.toName…)之类:使用Get.toName,肯定须要使用GetPage;如果使用Get.to,是不须要在GetPage中注册的,Get.to的内部有一个添加到GetPageRoute的利用
通过上面会在GetPage注册可知,阐明在我们跳转页面的时候,GetX会拿你到页面信息存储起来,加以管理,下面俩种场景会导致GetxController无法释放
- 未使用GetX提供的路由跳转:直接使用原生路由api的跳转利用
- 这样会直接导致GetX无法感知对应页面GetxController的生命周期,会导致其无法释放
- 在GetPage注册页面,不使用Get.toName,这样无法释放;GetPage+Get.toName配套使用可释放
- 直接使用Get.to,可释放
Navigator.push(
context,
MaterialPageRoute(builder: (context) => XxxxPage()),
);
- 一般app都是,一个主页面,加几个tab:首页、信息流页、利用页、个人中央之类
- 如果你遇到须要重新登录,再回到主页,你可能会发现个人中央这些页面的GetxController控制未被回收!
- 这些页面已经和上面的路由页面无关了,由于他们本身只能算是主页面上的几个tab子页面,没法用路由去标定绑定关系
办理方案
这边我模拟了上面场景,写了一个办理方案
Navigator.push(
Get.context,
MaterialPageRoute(builder: (context) => AutoDisposePage()),
);
- 演示页面
- 这地方地方必须要使用StatefulWidget,由于在这种环境,无法感知生命周期,就须要使用StatefulWidget生命周期
- 在dispose回调处,把当前GetxController从整个GetxController管理链中删除即可
class AutoDisposePage extends StatefulWidget {
@override
_AutoDisposePageState createState() => _AutoDisposePageState();
}
class _AutoDisposePageState extends State {
final AutoDisposeLogic logic = Get.put(AutoDisposeLogic());
@override
Widget build(BuildContext context) {
return BaseScaffold(
appBar: AppBar(title: const Text(‘计数器-自动释放’)),
body: Center(
child: Obx(
() => Text(‘点击了 ${logic.count.value} 次’,
style: TextStyle(fontSize: 30.0)),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => logic.increase(),
child: const Icon(Icons.add),
),
);
}
@override
void dispose() {
Get.delete();
super.dispose();
}
}
class AutoDisposeLogic extends GetxController {
var count = 0.obs;
///自增
void increase() => ++count;
}
看到这,你可能会想,啊这!怎么这么贫苦,我怎么还要写StatefulWidget,好贫苦!
各位放心,这个题目,我也想到了,我专程在插件里面加上了自动回收的功能
- 如果你写的页面无法被回收,记得勾选autoDispose
- 怎么判断页面的GetxController是否能被回收呢?实际上很简单,上面的未被释放的场景已经形貌的比较清晰了,不清晰的话,就再看看
[外链图片转存中…(img-1X07NA91-1734683976539)]
来看下代码,default模式一样可以的
class AutoDisposePage extends StatefulWidget {
@override
_AutoDisposePageState createState() => _AutoDisposePageState();
}
class _AutoDisposePageState extends State {
final AutoDisposeLogic logic = Get.put(AutoDisposeLogic());
@override
Widget build(BuildContext context) {
return Container();
}
@override
void dispose() {
Get.delete();
super.dispose();
}
}
class AutoDisposeLogic extends GetxController {
}
好了,接下来,进入正文吧!
计数器
效果图
[外链图片转存中…(img-Aus6UrXC-1734683976540)]
实现
首页,当然是实现一个简单的计数器,来看GetX怎么将逻辑层和界面层解耦的
- 来使用插件生成下简单文件
- 模式选择:Easy
- 功能选择:useFolder
[外链图片转存中…(img-3lIPztqk-1734683976540)]
来看下生成的默认代码,默认代码非常简单,具体解释放在俩种状态管理里
import ‘package:get/get.dart’;
class CounterGetLogic extends GetxController {
}
import ‘package:flutter/material.dart’;
import ‘package:get/get.dart’;
import ‘logic.dart’;
class CounterGetPage extends StatelessWidget {
final CounterGetLogic logic = Get.put(CounterGetLogic());
@override
Widget build(BuildContext context) {
return Container();
}
}
响应式状态管理
当数据源变化时,将自动执行革新组件的方法
- logic层
- 由于是处理页面逻辑的,加上Controller单词过长,也防止和Flutter自带的一些控件控制器弄混,所以该层用logic结尾,这里就定为了logic层,当然这点随个人意向,写Event,Controller均可
- 这里变量数值后写.obs利用,是阐明定义了该变量为响应式变量,当该变量数值变化时,页面的革新方法将自动革新;基础范例,List,类都可以加.obs,使其变成响应式变量
class CounterGetLogic extends GetxController {
var count = 0.obs;
///自增
void increase() => ++count;
}
- view层
- 这地方获取到Logic层的实例后,就可举行利用了,大家可能会想:WTF,为什么实例的利用放在build方法里?逗我呢?--------- 实际否则,stl是无状态组件,阐明白他就不会被二次重组,所以实例利用只会被执行一次,而且Obx()方法是可以革新组件的,完美办理革新组件题目了
class CounterGetPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
CounterGetLogic logic = Get.put(CounterGetLogic());
return Scaffold(
appBar: AppBar(title: const Text(‘GetX计数器’)),
body: Center(
child: Obx(
() => Text(‘点击了 ${logic.count.value} 次’,
style: TextStyle(fontSize: 30.0)),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => logic.increase(),
child: const Icon(Icons.add),
),
);
}
}
class CounterGetPage extends StatelessWidget {
final CounterGetLogic logic = Get.put(CounterGetLogic());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text(‘GetX计数器’)),
body: Center(
child: Obx(
() => Text(‘点击了 ${logic.count.value} 次’,
style: TextStyle(fontSize: 30.0)),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => logic.increase(),
child: const Icon(Icons.add),
),
);
}
}
- 可以发现革新组件的方法极其简单:Obx(),这样可以舒畅的到处写定点革新利用了
- Obx()方法革新的条件
- 只有当响应式变量的值发生变化时,才会会执行革新利用,当某个变量初始值为:“test”,再赋值为:“test”,并不会执行革新利用
- 当你定义了一个响应式变量,该响应式变量改变时,包裹该响应式变量的Obx()方法才会执行革新利用,别的的未包裹该响应式变量的Obx()方法并不会执行革新利用,Cool!
- 来看下如果把整个类对象设置成响应范例,怎样实现更新利用呢?
- 下面解释来自官方README文档
- 这里尝试了下,将整个类对象设置为响应范例,当你改变了类其中一个变量,然后执行更新利用,只要包裹了该响应类变量的Obx(),都会实验革新利用,将整个类设置响应范例,须要结合实际场景使用
// model
// 我们将使整个类成为可观察的,而不是每个属性。
class User{
User({this.name = ‘’, this.age = 0});
String name;
int age;
}
// controller
final user = User().obs;
//当你须要更新user变量时。
user.update( (user) { // 这个参数是你要更新的类本身。
user.name = ‘Jonny’;
user.age = 18;
});
// 更新user变量的另一种方式。
user(User(name: ‘João’, age: 35));
// view
Obx(()=> Text(“Name ${user.value.name}: Age: ${user.value.age}”));
// 你也可以不使用.value来访问模型值。
user().name; // 注意是user变量,而不是类变量(首字母是小写的)。
简单状态管理
GetBuilder:这是一个极其轻便的状态管理器,占用资源少少!
class CounterEasyGetLogic extends GetxController {
var count = 0;
void increase() {
++count;
update();
}
}
class CounterEasyGetPage extends StatelessWidget {
final CounterEasyGetLogic logic = Get.put(CounterEasyGetLogic());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text(‘计数器-简单式’)),
body: Center(
child: GetBuilder(
builder: (logicGet) => Text(
‘点击了 ${logicGet.count} 次’,
style: TextStyle(fontSize: 30.0),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => logic.increase(),
child: const Icon(Icons.add),
),
);
}
}
- 分析下:GetBuilder这个方法
- init:虽然上述代码没用到,但是,这个参数是存在在GetBuilder中的,由于在加载变量的时候就使用Get.put()生成了CounterEasyGetLogic对象,GetBuilder会自动查找该对象,所以,就可以不使用init参数
- builder:方法参数,拥有一个入参,范例便是GetBuilder所传入泛型的范例
- initState,dispose等:GetBuilder拥有StatefulWidget所有周期回调,可以在相应回调内做一些利用
总结
分析
- Obx是配合Rx响应式变量使用、GetBuilder是配合update使用:请注意,这完全是俩套定点革新控件的方案
- 区别:前者响应式变量变化,Obx自动革新;后者须要使用update手动调用革新
- 响应式变量,由于使用的是StreamBuilder,会消耗一定资源
- GetBuilder内部实际上是对StatefulWidget的封装,所以占用资源极小
使用场景
- 一般来说,对于大多数场景都是可以使用响应式变量的
- 但是,在一个包含了大量对象的List,都使用响应式变量,将生成大量的StreamBuilder,必将对内存造成较大的压力,该环境下,就要考虑使用简单状态管理了
跨页面交互
跨页面交互,在复杂的场景中,是非常紧张的功能,来看看GetX怎么实现跨页面事件交互的
效果图
- 体验一下
- Cool,这才是真正的跨页面交互!下级页面能随意调用上级页面事件,且关闭页面后,下次重进,数据也很天然重置了(全局Bloc不会重置,须要手动重置)
[外链图片转存中…(img-gVZeIzJz-1734683976540)]
实现
页面一
常规代码
- logic
- 这里的自增事件,是供别的页面调用的,该页面本身没使用
class JumpOneLogic extends GetxController {
var count = 0.obs;
///跳转到跨页面
void toJumpTwo() {
Get.toNamed(RouteConfig.jumpTwo, arguments: {‘msg’: ‘我是上个页面传递过来的数据’});
}
///跳转到跨页面
void increase() => count++;
}
class JumpOnePage extends StatelessWidget {
/// 使用Get.put()实例化你的类,使其对当下的所有子路由可用。
final JumpOneLogic logic = Get.put(JumpOneLogic());
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(title: Text(‘跨页面-One’)),
floatingActionButton: FloatingActionButton(
onPressed: () => logic.toJumpTwo(),
child: const Icon(Icons.arrow_forward_outlined),
),
body: Center(
child: Obx(
() => Text(‘跨页面-Two点击了 ${logic.count.value} 次’,
style: TextStyle(fontSize: 30.0)),
),
),
);
}
}
页面二
这个页面就是重点了
- logic
- 将演示怎么调用前一个页面的事件
- 怎么接收上个页面数据
- 请注意,GetxController包含比较完备的生命周期回调,可以在onInit()接受传递的数据;如果接收的数据须要革新到界面上,请在onReady回调里面接收数据利用,onReady是在addPostFrameCallback回调中调用,革新数据的利用在onReady举行,能保证界面是初始加载完毕后才举行页面革新利用的
class JumpTwoLogic extends GetxController {
var count = 0.obs;
var msg = ‘’.obs;
@override
void onReady() {
var map = Get.arguments;
msg.value = map[‘msg’];
super.onReady();
}
///跳转到跨页面
void increase() => count++;
}
- view
- 加号的点击事件,点击时,能实现俩个页面数据的变换
- 重点来了,这里通过Get.find(),获取到了之前实例化GetXController,获取某个模块的GetXController后就很好做了,可以通过这个GetXController去调用相应的事件,也可以通过它,拿到该模块的数据!
class JumpTwoPage extends StatelessWidget {
final JumpOneLogic oneLogic = Get.find();
final JumpTwoLogic twoLogic = Get.put(JumpTwoLogic());
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(title: Text(‘跨页面-Two’)),
floatingActionButton: FloatingActionButton(
onPressed: () {
oneLogic.increase();
twoLogic.increase();
},
child: const Icon(Icons.add),
),
body: Center(
child: Column(mainAxisSize: MainAxisSize.min, children: [
//计数显示
Obx(
() => Text(‘跨页面-Two点击了 ${twoLogic.count.value} 次’,
style: TextStyle(fontSize: 30.0)),
),
//传递数据
Obx(
() => Text(‘传递的数据:${twoLogic.msg.value}’,
style: TextStyle(fontSize: 30.0)),
),
]),
),
);
}
}
总结
GetX这种的跨页面交互事件,真的是非常简单了,侵入性也非常的低,不须要在主入口配置什么,在复杂的业务场景下,这样简单的跨页面交互方式,就能实现很多事了
进阶吧!计数器
我们可能会遇到过很多复杂的业务场景,在复杂的业务场景下,单单某个模块关于变量的初始化利用可能就非常多,在这个时候,如果还将state(状态层)和logic(逻辑层)写在一起,维护起来可能看的比较晕,这里将状态层和逻辑层举行一个拆分,这样在轻微大一点的项目里使用GetX,也能保证布局充足清晰了!
在这里就继续用计数器举例吧!
实现
此处须要分别三个布局了:state(状态层),logic(逻辑层),view(界面层)
- 这里使用插件生成下模板代码
- Model:选择Default(默认)
- Function:useFolder(默认中)
[外链图片转存中…(img-vjbJoEhi-1734683976540)]
来看下生成的模板代码
class CounterHighGetState {
CounterHighGetState() {
///Initialize variables
}
}
import ‘package:get/get.dart’;
import ‘state.dart’;
class CounterHighGetLogic extends GetxController {
final state = CounterHighGetState();
}
import ‘package:flutter/material.dart’;
import ‘package:get/get.dart’;
import ‘logic.dart’;
import ‘state.dart’;
class CounterHighGetPage extends StatelessWidget {
final CounterHighGetLogic logic = Get.put(CounterHighGetLogic());
final CounterHighGetState state = Get.find().state;
@override
Widget build(BuildContext context) {
return Container();
}
}
为什么写成这样三个模块,须要把State单独提出来,请速速欣赏下方
改造
- state
- 这里可以发现,count范例使用的是RxInt,没有使用var,使用该变量范例的缘故原由,此处是将所有的利用都放在构造函数里面初始化,如果直接使用var没有立马赋值,是无法推导为Rx范例,所以这里直接定义为RxInt,实际很简单,基础范例将开头字母大写,然后加上Rx前缀即可
- 实际上直接使用var也是可以的,但是,使用该响应变量的时候.value无法提示,须要自己手写,所以还是老老实实的写明Rx具体范例吧
- 具体可查看:声明响应式变量
class CounterHighGetState {
RxInt count;
CounterHighGetState() {
count = 0.obs;
}
}
- logic
- 逻辑层就比较简单,须要注意的是:开始时须要实例化状态类
class CounterHighGetLogic extends GetxController {
final state = CounterHighGetState();
///自增
void increase() => ++state.count;
}
- view
- 实际上view层,和之前的险些没区别,区别的是把状态层给独立出来了
- 由于CounterHighGetLogic被实例化,所以直接使用Get.find<CounterHighGetLogic>()就能拿到刚刚实例化的逻辑层,然后拿到state,使用单独的变量接收下
- ok,此时:logic只专注于触发事件交互,state只专注数据
class CounterHighGetPage extends StatelessWidget {
final CounterHighGetLogic logic = Get.put(CounterHighGetLogic());
final CounterHighGetState state = Get.find().state;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text(‘计数器-响应式’)),
body: Center(
child: Obx(
() => Text(‘点击了 ${state.count.value} 次’,
style: TextStyle(fontSize: 30.0)),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => logic.increase(),
child: const Icon(Icons.add),
),
);
}
}
对比
看了上面的改造,屏幕前的你可能想吐槽了:坑比啊,之前简简单单的逻辑层,被拆成俩个,还搞得这么贫苦,你是猴子请来的逗比吗?
大家先别急着吐槽,当业务过于复杂,state层,也是会维护很多东西的,让我们看看下面的一个小栗子,下面实例代码是不能直接运行的,想看具体运行代码,请查看项目:flutter_use
class MainState {
///选择index - 响应式
RxInt selectedIndex;
///控制是否睁开 - 响应式
RxBool isUnfold;
///分类按钮数据源
List list;
///Navigation的item信息
List itemList;
///PageView页面
List pageList;
PageController pageController;
MainState() {
//初始化index
selectedIndex = 0.obs;
//默认不睁开
isUnfold = false.obs;
//PageView页面
pageList = [
keepAliveWrapper(FunctionPage()),
keepAliveWrapper(ExamplePage()),
keepAliveWrapper(Center(child: Container())),
];
//item栏目
itemList = [
BtnInfo(
title: “功能”,
icon: Icon(Icons.bubble_chart),
),
BtnInfo(
title: “范例”,
icon: Icon(Icons.opacity),
),
BtnInfo(
title: “设置”,
icon: Icon(Icons.settings),
),
];
//页面控制器
pageController = PageController();
}
}
class MainLogic extends GetxController {
final state = MainState();
///切换tab
void switchTap(int index) {
state.selectedIndex.value = index;
}
///是否睁开侧边栏
void onUnfold(bool unfold) {
state.isUnfold.value = !state.isUnfold.value;
}
}
class MainPage extends StatelessWidget {
final MainLogic logic = Get.put(MainLogic());
final MainState state = Get.find().state;
@override
Widget build(BuildContext context) {
return BaseScaffold(
backgroundColor: Colors.white,
body: Row(children: [
///侧边栏区域
Obx(
() => SideNavigation(
selectedIndex: state.selectedIndex.value,
sideItems: state.itemList,
onItem: (index) {
logic.switchTap(index);
state.pageController.jumpToPage(index);
},
isUnfold: state.isUnfold.value,
onUnfold: (unfold) {
logic.onUnfold(unfold);
},
),
),
///Expanded占满剩下的空间
Expanded(
child: PageView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: state.pageList.length,
itemBuilder: (context, index) => state.pageList[index],
controller: state.pageController,
),
)
]),
);
}
}
从上面可以看出,state层里面的状态已经较多了,当某些模块涉及到大量的:提交表单数据,跳转数据,展示数据等等,state层的代码会相当的多,相信我,真的是非常多,一旦业务发生变更,还要经常维护修改,就蛋筒了
在复杂的业务下,将状态层(state)和业务逻辑层(logic)分开,绝对是个明智的举动
最后
- 该模块的效果图就不放了,和上面计数器效果一模一样,想体验一下,可点击:体验一下
- 简单的业务模块,可以使用俩层布局:logic,view;复杂的业务模块,推荐使用三层布局:state,logic,view
路由管理
GetX实现了一套用起来非常简单的路由管理,可以使用一种极其简单的方式导航,也可以使用命名路由导航
关于简单路由和命名路由的区别
Get.to(SomePage());
- 命名路由
- 在web上,可以直接通过命名的url直接导航页面
- 实现路由拦截的利用,举一个官方文档的例子:很轻松的实现了一个未登录,跳转登录页面功能
GetStorage box = GetStorage();
GetMaterialApp(
getPages: [
GetPage(name: ‘/’, page ){
return box.hasData(‘token’) ? Home() : Login();
})
]
)
简单路由
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
home: MainPage(),
);
}
}
- 路由的相关使用
- 使用是非常简单,使用Get.to()之类api即可,此处简单演示,具体api阐明,放在本节结尾
//跳转新页面
Get.to(SomePage());
命名路由导航
这里是推荐使用命名路由导航的方式
- 统一管理起了所有页面
- 在app中可能感受不到,但是在web端,加载页面的url地点就是命名路由你所设置字符串,也就是说,在web中,可以直接通过url导航到相关页面
下面阐明下,怎样使用
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: RouteConfig.main,
getPages: RouteConfig.getPages,
);
}
}
- RouteConfig类
- 下面是我的相关页面,和其映射的页面,请根据自己的页面举行相关编写
class RouteConfig{
///主页面
static final String main = “/”;
///dialog页面
static final String dialog = “/dialog”;
///bloc计数器模块
static final String counter = “/counter”;
///测试布局页面
static final String testLayout = “/testLayout”;
///演示SmartDialog控件
static final String smartDialog = “/smartDialog”;
///Bloc跨页面传递事件
static final String spanOne = “/spanOne”;
static final String spanTwo = “/spanOne/spanTwo”;
///GetX 计数器 跨页面交互
static final String counterGet = “/counterGet”;
static final String jumpOne = “/jumpOne”;
static final String jumpTwo = “/jumpOne/jumpTwo”;
///别名映射页面
static final List getPages = [
GetPage(name: main, page: () => MainPage()),
p(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: RouteConfig.main,
getPages: RouteConfig.getPages,
);
}
}
- RouteConfig类
- 下面是我的相关页面,和其映射的页面,请根据自己的页面举行相关编写
class RouteConfig{
///主页面
static final String main = “/”;
///dialog页面
static final String dialog = “/dialog”;
///bloc计数器模块
static final String counter = “/counter”;
///测试布局页面
static final String testLayout = “/testLayout”;
///演示SmartDialog控件
static final String smartDialog = “/smartDialog”;
///Bloc跨页面传递事件
static final String spanOne = “/spanOne”;
static final String spanTwo = “/spanOne/spanTwo”;
///GetX 计数器 跨页面交互
static final String counterGet = “/counterGet”;
static final String jumpOne = “/jumpOne”;
static final String jumpTwo = “/jumpOne/jumpTwo”;
///别名映射页面
static final List getPages = [
GetPage(name: main, page: () => MainPage()),
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |