当前位置: 首页 > news >正文

开锁换锁公司网站模板重庆网站建设找承越

开锁换锁公司网站模板,重庆网站建设找承越,百度首页 百度,网站网站制作价格建站网站前言 状态管理 / 路由管理 / 依赖管理 这三部分之间存在联系 参考文章 建议看官网文章#xff0c;很详细 #xff0c;pub.dev搜索get pub.dev的文档 状态管理文章相关链接 状态管理 案例 实现一个计算器#xff0c;运用GetX去管理它 构建界面 构建一个计算器界面 …前言 状态管理 / 路由管理 / 依赖管理 这三部分之间存在联系 参考文章 建议看官网文章很详细 pub.dev搜索get pub.dev的文档 状态管理文章相关链接 状态管理 案例 实现一个计算器运用GetX去管理它 构建界面 构建一个计算器界面 flutter_screenutil: ^5.9.0import package:flutter/material.dart; import package:flutter_screenutil/flutter_screenutil.dart;void main() {runApp(App()); }class App extends StatelessWidget {overrideWidget build(BuildContext context) {return ScreenUtilInit(builder: (_, child) {return MaterialApp(debugShowCheckedModeBanner: false,home: child,);},child: Main(),);} }class Main extends StatelessWidget {final Color operatorColor const Color.fromRGBO(93, 93, 93, 1);final Color numberColor const Color.fromRGBO(119, 119, 119, 1);final Color operatorColorTwo const Color.fromRGBO(242, 163, 60, 1);final Color borderColor const Color.fromRGBO(76, 76, 76, 1);const Main({super.key});overrideWidget build(BuildContext context) {return SafeArea(child: Scaffold(body: Column(children: [buildUserButton(text: 0,bgColor: operatorColor,width: 1.sw,alignment: Alignment.centerRight,fontSize: 60.r,padding: EdgeInsets.symmetric(horizontal: 25.r),),Row(children: [buildUserButton(text: AC, bgColor: operatorColor),buildUserButton(text: ±, bgColor: operatorColor),buildUserButton(text: %, bgColor: operatorColor),buildUserButton(text: ÷, bgColor: operatorColorTwo),],),Row(children: [buildUserButton(text: 7, bgColor: numberColor),buildUserButton(text: 8, bgColor: numberColor),buildUserButton(text: 9, bgColor: numberColor),buildUserButton(text: ×, bgColor: operatorColorTwo),],),Row(children: [buildUserButton(text: 4, bgColor: numberColor),buildUserButton(text: 5, bgColor: numberColor),buildUserButton(text: 6, bgColor: numberColor),buildUserButton(text: -, bgColor: operatorColorTwo),],),Row(children: [buildUserButton(text: 1, bgColor: numberColor),buildUserButton(text: 2, bgColor: numberColor),buildUserButton(text: 3, bgColor: numberColor),buildUserButton(text: , bgColor: operatorColorTwo),],),Row(children: [buildUserButton(text: 0,bgColor: numberColor,width: 1.sw / 2,),buildUserButton(text: ., bgColor: numberColor),buildUserButton(text: , bgColor: operatorColorTwo),],),],),),);}Widget buildUserButton({required String text,required Color bgColor,double? width,Alignment? alignment,double? fontSize,EdgeInsetsGeometry? padding,}) {return Container(alignment: alignment ?? Alignment.center,width: width ?? 1.sw / 4,height: 1.sw / 4,decoration: BoxDecoration(color: bgColor,border: Border.all(color: borderColor),),padding: padding ?? EdgeInsets.all(10.r),child: Text(text,style: TextStyle(color: const Color.fromRGBO(235, 235, 235, 1),fontSize: fontSize ?? 30.r,),),);} }采用GetX实现 引入getX get: ^4.6.6.obs 和 Obx(() View()) 计算器输入数字 说明需要跟踪的变量加上后缀.obs。这样的写法我说明一下。其实是源于dart语言的extension即扩展。比如对文本进行扩展那么文本类型的数据就会有你定义的功能。见下 extension MyStringExtension on String {String get sayHello {String words $this say hello!!!;return words;} }void main() {print(阿笙.sayHello);/// 阿笙 say hello!!! }同样的.obs就是对各种数据类型进行扩展 显然不止文本一个还有很多这里一一列举/使用可以参考官网的说明文档 String / bool / double / int 这四个写法类似。 响应式变量相关 Rx{类型}传入泛型利用扩展函数(推荐) /// 文本类型final stringType1 RxString();final stringType2 RxString();final stringType3 .obs;Obx(() {return Text(stringType1.value);// return Text(stringType2.value);// return Text(stringType3.value);}),ElevatedButton(onPressed: () {stringType1.value DateTime.timestamp().toString();// stringType2.value DateTime.timestamp().toString();// stringType3.value DateTime.timestamp().toString();},child: const Text(update),)只需在需要变化的界面中嵌套Obx() 这里提一句Obx()是自动刷新界面即当响应式变量变化时重构包裹内的界面区别于之后会提到的GetBuilder()GetBuilder()是手动更新界面。具体使用哪一个请根据应用场景。 写法都类似 /// 布尔final boolType1 RxBool(true);final boolType2 Rxbool(true);final boolType3 true.obs;/// 整型final intType1 RxInt(0);final intType2 Rxint(0);final intType3 0.obs;/// 浮点final doubleType1 RxDouble(0.0);final doubleType2 Rxdouble(0.0);final doubleType3 0.0.obs;Obx(() {return Checkbox(value: boolType3.value,onChanged: (v) {},);}),Obx(() {return Text(${intType3.value});}),Obx(() {return Text(${doubleType3.value});}),ElevatedButton(onPressed: () {boolType3.value !boolType3.value;intType3.value 1;doubleType3.value 0.1;},child: const Text(update),)List的写法稍有不同 /// 列表final listType1 RxListString(String[]);final listType3 String[].obs;Obx(() {return ListView.builder(shrinkWrap: true,itemBuilder: (ctx, index) {return Text(listType1.elementAt(index));// return Text(listType3.elementAt(index));},itemCount: listType1.length,// itemCount: listType3.length,);}),ElevatedButton(onPressed: () {listType1.add(DateTime.timestamp().toString());// listType3.add(DateTime.timestamp().toString());},child: const Text(add),)第二种申明方式 Obx(() {return ListView.builder(shrinkWrap: true,itemBuilder: (ctx, index) {return Text(listType2.value.elementAt(index));// return Text(listType3.elementAt(index));},itemCount: listType2.value.length,// itemCount: listType3.length,);}),ElevatedButton(onPressed: () {listType2.update((val) {val?.add(DateTime.timestamp().toString());});// listType3.add(DateTime.timestamp().toString());},child: const Text(add),)Map响应式变量用法也各有不同写的不对的话Obx()内的界面不会更新 /// 键值对final mapType1 RxMapString, int({});final mapType2 RxMapString, int({});final mapType3 MapString, int{}.obs;/// RxMapString, int({})Obx(() {return Text(${mapType1[count] ?? 无});}),ElevatedButton(onPressed: () {if (mapType1.isEmpty) {mapType1[count] 0;}mapType1[count] mapType1[count]! 1;},child: const Text(add),),/// RxMapString, int({})Obx(() {return Text(${mapType2.value[count] ?? 无});}),ElevatedButton(onPressed: () {if (mapType2.value.isEmpty) {mapType2.value[count] 0;}mapType2.update((val) {mapType2.value[count] mapType2.value[count]! 1;});},child: const Text(add),),/// MapString, int{}.obsObx(() {return Text(${mapType3.singleOrNull?[count] ?? 无});}),ElevatedButton(onPressed: () {if (mapType3.isEmpty) {mapType3.add({count: 0});}mapType3.update((value) {mapType3.single[count] mapType3.single[count]! 1;});},child: const Text(add),)申明响应式对象使用update更新 /// 对象final cusClassType1 RxCustomClass(CustomClass());final cusClassType2 CustomClass().obs;Obx(() {return Text(cusClassType1.value.property);// return Text(cusClassType2.value.property);}),ElevatedButton(onPressed: () {cusClassType1.update((val) {val?.property hello\n;});// cusClassType2.update((val) {// val?.property hello\n;// });},child: const Text(say hello),)输入数字 继续案例 在声明好响应式变量后定义点击事件 void numberOperator(String value) {result.value value;}当点击数字时会使Obx()包裹的界面重构 GetX 除了Obx来自动刷新布局还可以采用GetX同样是自动刷新但需要GetxController 先定义一个子类CalculatorController并将之前逻辑的部分都放进这个CalculatorController中 import package:get/get.dart;class CalculatorController extends GetxController {final result .obs;int get resultLength result.value.length 9 ? 9 : result.value.length;String get text result.value.isEmpty ? 0 : result.value;void numberOperator(String value) {result.value value;} }GetXCalculatorController(init: controller,builder: (logic) {return buildCalculatorBlock(text: logic.text,bgColor: operatorColor,width: 1.sw,alignment: Alignment.centerRight,fontSize: (60 * 9 / logic.resultLength).r,padding: EdgeInsets.symmetric(horizontal: 25.r),);},),运行之后点击数字也能自动刷新 相比ObX他有初始化状态可以将逻辑部分归类到GetXController中 GetBuilder update 除了Obx和GetX这两种自动刷新还有手动刷新的方式那就是采用GetBuilder 之前在GetX中创建好Controller在这里仍然需要使用 鼠标点在需要包裹的Widget中按下【option】和【回车】就能看到 同样需要初始化controller因为只需要刷新上面计算的结果所以只需要包裹需要刷新的部分这很重要。 看我上面的截图是可以输入数字的但是这里还需要一步你们才能刷新。这就是为什么GetBuilder是手动刷新了。 如果不调用需要刷新的界面不会刷新 同时可以再简化因为obs响应式变量是配合自动刷新的GetX和ObX来使用的在这里既然都手动刷新了那可以不采用响应式变量当然你也可以留着。 改为普通的String通过配合update结果也能刷新。 只有你点击即调用update才会刷新对应的布局 GetBuilder 指定id 和 回调函数 GetBuilder不仅有statefulWidget那种生命周期回调函数还可以可以指定id指定特定的界面刷新数据 import package:flutter/material.dart; import package:get/get_state_manager/src/simple/get_state.dart; import controller.dart;void main() {runApp(App()); }class App extends StatelessWidget {overrideWidget build(BuildContext context) {return MaterialApp(home: Main());} }class Main extends StatelessWidget {final controller Controller();overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [GetBuilderController(init: controller,initState: (_) {controller.addLog(initState);},didChangeDependencies: (_) {controller.addLog(didChangeDependencies);},didUpdateWidget: (_, __) {controller.addLog(didUpdateWidget);},dispose: (_) {controller.addLog(dispose);},builder: (logic) {return Column(mainAxisSize: MainAxisSize.min,children: logic.log.map((e) Text(e)).toList(),);},),const Divider(),GetBuilderController(id: mine,init: controller,builder: (logic) {return Column(mainAxisSize: MainAxisSize.min,children: logic.log.map((e) Text(e)).toList(),);},),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ElevatedButton(onPressed: () {controller.updateLog();},child: const Text(刷新 update),),ElevatedButton(onPressed: () {controller.updateMineLog();},child: const Text(刷新mine update([mine])),),],),],),),);} }import package:get/get.dart;class Controller extends GetxController {ListString log [];addLog(String logContent) {log.add(logContent);}updateLog() {log.add(update - ${DateTime.now().toIso8601String()});update();}updateMineLog() {update([mine]);} }GetxController的回调函数 可以看到initState要优先于onInit接着当界面加载出来之后再会执行到onReady当Get.delete掉GetxController最后会调用到onClose。当然之后有了依赖管理和绑定后无需去删除GetxController 所以有了这三个onInit / onReady / onClose就能完成大部分功能了。GetBuilder里面的回调不是必须使用 onInit一般用于初始化数据界面还没有出来时当界面首次出来后会回调onReady当你使用了例如流这种需要销毁的控制器页面关闭后都要在onClose中销毁 import package:get/get.dart;class Controller extends GetxController {ListString log [];addLog(String logContent) {log.add(logContent);}updateLog() {log.add(update - ${DateTime.now().toIso8601String()});update();}overridevoid onInit() {log.add(onInit);super.onInit();}overridevoid onReady() {log.add(onReady);update();super.onReady();}overridevoid onClose() {print(controller - onClose);super.onClose();} }import package:flutter/material.dart; import package:get/get_state_manager/src/simple/get_state.dart; import package:get/instance_manager.dart; import controller.dart;void main() {runApp(App()); }class App extends StatelessWidget {overrideWidget build(BuildContext context) {return MaterialApp(home: Main());} }class Main extends StatelessWidget {final controller Controller();overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [GetBuilderController(init: controller,initState: (_) {controller.addLog(initState);},didChangeDependencies: (_) {controller.addLog(didChangeDependencies);},didUpdateWidget: (_, __) {controller.addLog(didUpdateWidget);},dispose: (_) {controller.addLog(dispose);},builder: (logic) {return Column(mainAxisSize: MainAxisSize.min,children: logic.log.map((e) Text(e)).toList(),);},),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ElevatedButton(onPressed: () {Get.deleteController();// controller.updateLog();},child: const Text(刷新 update),),],),],),),);} }GetxController的爹 - SuperController 能监听到更多的事件。例如我将应用切到后台再切回来可以监听到我可以做刷新界面数据的操作 又比如我切换到后台就停止监听机器的数据节约流量。停止视频服务等 总之就是功能多一些这样 onDetachedonHiddenonInactiveonPausedonResumed import package:get/get.dart;class Controller extends SuperController {ListString log [];addLog(String logContent) {log.add(logContent);}updateLog() {log.add(update - ${DateTime.now().toIso8601String()});update();}overridevoid onInit() {log.add(onInit);super.onInit();}overridevoid onReady() {log.add(onReady);update();super.onReady();}overridevoid onClose() {print(controller - onClose);super.onClose();}overridevoid onDetached() {// TODO: implement onDetached}overridevoid onHidden() {// TODO: implement onHidden}overridevoid onInactive() {// TODO: implement onInactive}overridevoid onPaused() {// TODO: implement onPaused}overridevoid onResumed() {// TODO: implement onResumed} } 依赖管理 Get.put 之前有用到GetsController那么配合它可以使用注册依赖来达到多页面使用 回到之前的案例 我们构建了一个计算器。现在跳转到下一个界面并获取输入的数据 实现的效果 改写用Get.put 页面跳转需要Get.to而使用路由相关功能需要使用GetMaterialApp final controller Get.putCalculatorController(CalculatorController());floatingActionButton: FloatingActionButton(onPressed: () {Get.to(() NextPage());},child: const Text(下一页),),而在另一个界面中需要通过Get.find来找到之前注册的Controller 最终取到了Controller里面的数值 继续改造(Get.lazyput Bindings) 现在写下来代码很乱所以整理一下 新建一个文件夹里面放上四个空文件之后会采用插件生成代码现在先写一遍 main-binding.dart 绑定层用于注册Controllermain_logic.dart 逻辑层就是之前的GetxController只写逻辑main_state.dart 状态层是存放你的变量的地方以及初始化你的变量main_view.dart 界面层只写界面不写任何逻辑 将main.dart中的所有代码都转移到main_view.dart 接着移动controller到绑定层并改写为Get.lazyput。 Get.lazyPutCalculatorController(() CalculatorController());Get.put / Get.lazyPut / Get.putAsync Get.put 就是普通的注册依赖的方式Get.lazyPut 是懒注册依赖当有用到时它就加载这个依赖Get.putAsync 是异步注册 Get.find 继续改造通过Get.find并传入你定义的Controller泛型就可以得到一个对象。这样就不会报错了 注意要定义在build内 GetMaterialApp - initBinding 最后一步在GetMaterialApp中使用的bindings main_logic 将之前定义好的controller放进逻辑层中可以改个名字代表main这一部分的逻辑层。直接删掉之前的文件 main_logic main_state 将变量放进状态层留下逻辑函数 next_page 运行项目 命名路由 使用别名路由在GetMaterialApp中注册路由及绑定并设置初始路径 路由以‘/’开头 static String routeName /main;import package:flutter/material.dart; import package:flutter_gext_application/main/main_binding.dart; import package:flutter_screenutil/flutter_screenutil.dart; import package:get/get.dart;import main/main_view.dart;void main() {runApp(App()); }class App extends StatelessWidget {overrideWidget build(BuildContext context) {return ScreenUtilInit(builder: (_, child) {return GetMaterialApp(debugShowCheckedModeBanner: false,initialRoute: Main.routeName,getPages: [GetPage(name: Main.routeName,page: () Main(),binding: MainBinding(),),],);},child: Main(),);} }路由管理 注册路由 普通路由 home为最初的路由 Get.to() 跳转至一个新的页面 (Pushes a new page to the stack) Get.to(() const BPage());Get.off() 关闭当前的页面并进入一个新的页面Pop the current page and pushes a new page to the stack Get.off(() const BPage());Get.offAll() 关闭所有的页面并进入一个新的页面Push a page and pop several pages in the stack until predicate returns true. predicate is optional Get.offAll(() const BPage());Get.back() 返回上一个页面 案例 A - B - C --(to / off / offAll)– D import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return const GetMaterialApp(home: APage(),);} }class APage extends StatelessWidget {const APage({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(A页面),ElevatedButton(onPressed: () {Get.to(() const BPage());},child: const Text(跳转至B页面),),],),),);} }class BPage extends StatelessWidget {const BPage({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(B页面),ElevatedButton(onPressed: () {Get.to(() const CPage());},child: const Text(跳转至C页面),),],),),);} }class CPage extends StatelessWidget {const CPage({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(C页面),ElevatedButton(onPressed: () {Get.to(() const DPage());// Get.off(() const DPage());// Get.offAll(() const DPage());},child: const Text(跳转至D页面),),],),),);} }class DPage extends StatelessWidget {const DPage({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(D页面),ElevatedButton(onPressed: () {Get.back();},child: const Text(返回上一个页面),),],),),);} } 别名路由 给每一个页面都定一个根路由和跳转路由 A - B - C - D import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(initialRoute: APage.routeName,getPages: [GetPage(name: APage.rootName,page: () APage(),children: [GetPage(name: BPage.rootName,page: () BPage(),children: [GetPage(name: CPage.rootName,page: () CPage(),children: [GetPage(name: DPage.rootName,page: () DPage(),),],),],),],),],);} }class APage extends StatelessWidget {static String routeName /a;static String rootName /a;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(A页面),ElevatedButton(onPressed: () {Get.toNamed(BPage.routeName);},child: const Text(跳转至B页面),),],),),);} }class BPage extends StatelessWidget {static String routeName ${APage.routeName}$rootName;static String rootName /b;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(B页面),ElevatedButton(onPressed: () {Get.toNamed(CPage.routeName);},child: const Text(跳转至C页面),),],),),);} }class CPage extends StatelessWidget {static String routeName ${BPage.routeName}$rootName;static String rootName /c;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(C页面),ElevatedButton(onPressed: () {Get.toNamed(DPage.routeName);// Get.off(() const DPage());// Get.offAll(() const DPage());},child: const Text(跳转至D页面),),],),),);} }class DPage extends StatelessWidget {static String routeName ${CPage.routeName}$rootName;static String rootName /d;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(D页面),ElevatedButton(onPressed: () {Get.back();},child: const Text(返回上一个页面),),],),),);} }以上的写法是A的子页面有BB的子页面是CC的子页面是D Get.toNamed() 跳转到新页面 Get.toNamed(/a);Get.offNamed() 关闭当前页面跳转到新页面 Get.offNamed(/a);Get.offAllNamed() 关闭所有页面跳转到新页面 Get.offAllNamed(/a);import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(initialRoute: APage.routeName,getPages: [GetPage(name: APage.rootName,page: () APage(),children: [GetPage(name: BPage.rootName,page: () BPage(),children: [GetPage(name: CPage.rootName,page: () CPage(),children: [GetPage(name: DPage.rootName,page: () DPage(),),],),],),],),],);} }class APage extends StatelessWidget {static String routeName /a;static String rootName /a;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(A页面),ElevatedButton(onPressed: () {Get.toNamed(BPage.routeName);},child: const Text(跳转至B页面),),],),),);} }class BPage extends StatelessWidget {static String routeName ${APage.routeName}$rootName;static String rootName /b;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(B页面),ElevatedButton(onPressed: () {Get.toNamed(CPage.routeName);},child: const Text(跳转至C页面),),],),),);} }class CPage extends StatelessWidget {static String routeName ${BPage.routeName}$rootName;static String rootName /c;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(C页面),ElevatedButton(onPressed: () {Get.toNamed(DPage.routeName);// Get.offNamed(DPage.routeName);// Get.offAllNamed(DPage.routeName);},child: const Text(跳转至D页面),),],),),);} }class DPage extends StatelessWidget {static String routeName ${CPage.routeName}$rootName;static String rootName /d;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(D页面),ElevatedButton(onPressed: () {Get.back();},child: const Text(返回上一个页面),),],),),);} }未知路由 当用户输入一个不存在的路径返回一个指定页面 unknownRoute: GetPage(name: /notfound, page: () const UnknownPage())class UnknownPage extends StatelessWidget {const UnknownPage({super.key});overrideWidget build(BuildContext context) {return const Scaffold(body: Center(child: Text(404,style: TextStyle(fontSize: 40,),),),);} }传参数 有三种方式 Get.to(arguments: {}) 页面切到下一个页面可以在argument中直接附带参数。 import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(initialRoute: APage.routeName,getPages: [GetPage(name: APage.rootName,page: () APage(),children: [GetPage(name: BPage.rootName,page: () BPage(),),],),],);} }class APage extends StatelessWidget {static String routeName /a;static String rootName /a;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(A页面),ElevatedButton(onPressed: () {Get.toNamed(BPage.routeName,arguments: {paramA: hello,paramB: {name: sheng_er_sheng,blog: 1,}},);},child: const Text(跳转至B页面),),],),),);} }class BPage extends StatelessWidget {static String routeName ${APage.routeName}$rootName;static String rootName /b;final paramA Get.arguments[paramA];final paramBName Get.arguments[paramB][name];final paramBBlog Get.arguments[paramB][blog];overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(B页面),Text($paramA, $paramBName, $paramBBlog),],),),);} }Get.toNamed() 路径带参数 页面切到下一个页面可以在路由上附带参数。 这里要采用别名路由很明显是网址携带参数的写法 ?加个参数名后面接参数值如果有第二个参数就用链接一下然后继续参数名接一个参数值 这样即便没有前一个页面也能通过这种传参数的方式进入到这个页面 比如我换一个网址但是参数可以改动 这是代码中指定的参数值 import dart:convert;import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(initialRoute: APage.routeName,getPages: [GetPage(name: APage.rootName,page: () APage(),children: [GetPage(name: BPage.rootName,page: () BPage(),),],),],);} }class APage extends StatelessWidget {static String routeName /a;static String rootName /a;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(A页面),ElevatedButton(onPressed: () {const paramA hello;final paramB {name: 双笙,blog: 1,};Get.toNamed(${BPage.routeName}?paramA$paramAparamB${json.encode(paramB)});},child: const Text(跳转至B页面),),],),),);} }class BPage extends StatelessWidget {static String routeName ${APage.routeName}$rootName;static String rootName /b;final paramA Get.parameters[paramA];final paramBName json.decode(Get.parameters[paramB]!)[name];final paramBBlog json.decode(Get.parameters[paramB]!)[blog];overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(B页面),Text($paramA, $paramBName, $paramBBlog),],),),);} }在路由上规定参数(命名参数) 路由上定义参数名 这种写法需要注册路由 import dart:convert;import package:flutter/material.dart; import package:get/get.dart;import aPage.dart; import bPage.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(initialRoute: APage.routeName,getPages: [GetPage(name: APage.rootName,page: () APage(),children: [GetPage(name: BPage.rootName,page: () BPage(),),GetPage(name: ${BPage.rootName}/:paramA,page: () BPage(),),],),],);} }import dart:convert;import package:flutter/material.dart; import package:get/get.dart;import bPage.dart;class APage extends StatelessWidget {static String routeName /a;static String rootName /a;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(A页面),ElevatedButton(onPressed: () {const paramA hello;const paramB {name: 双笙,blog: 1,};Get.toNamed(${BPage.routeName}/$paramA?paramB${json.encode(paramB)},);},child: const Text(跳转至B页面),),],),),);} }import dart:convert;import package:flutter/material.dart; import package:get/get.dart;import aPage.dart;class BPage extends StatelessWidget {static String routeName ${APage.routeName}$rootName;static String rootName /b;final paramA Get.parameters[paramA];final paramB json.decode(Get.parameters[paramB]!);overrideWidget build(BuildContext context) {final paramBName paramB[name];final paramBBlog paramB[blog];return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(B页面),Text($paramA, $paramBName, $paramBBlog),],),),);} }中间件 案例 描述进入一个页面但是这个页面需要登录。如果登录过就直接进入这个页面否则跳转至登录页面 main --(没有登录)- login --(返回首页)- main --(已登录)- vip import package:flutter/material.dart; import package:get/get.dart;bool isLogin false;void main() {runApp(App()); }class App extends StatelessWidget {overrideWidget build(BuildContext context) {return GetMaterialApp(debugShowCheckedModeBanner: false,initialRoute: Main.routeName,getPages: [GetPage(name: Main.routeName,page: () Main(),),GetPage(name: Login.routeName,page: () Login(),),GetPage(name: Vip.routeName,page: () Vip(),middlewares: [LoginMiddleware(),],),],);} }class Main extends StatelessWidget {static String routeName /main;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(主页),ElevatedButton(onPressed: () {Get.toNamed(Vip.routeName);},child: const Text(VIP页面),),],),),);} }class Vip extends StatelessWidget {static String routeName /vip;overrideWidget build(BuildContext context) {return const Scaffold(body: Center(child: Text(欢迎VIP用户),),);} }class Login extends StatelessWidget {static String routeName /login;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(登录页面),ElevatedButton(onPressed: () {Get.snackbar(提示, 登录成功);isLogin true;Get.offAllNamed(Main.routeName);},child: const Text(我是马化腾),)],),),);} }class LoginMiddleware extends GetMiddleware {overrideRouteSettings? redirect(String? route) {if (route Vip.routeName) {Get.snackbar(提示, 请先登录);return isLogin ? null : RouteSettings(name: Login.routeName);} else {return null;}} }补充(routingCallback) 嵌套路由 跳转时带上id值为key值。点击会发现始终在/main路由下但是页面分别进入了三个内部的路由 最后进入完成页面 extension TitleText on Text {Text get title Text(data!,style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),); }import package:flutter/material.dart; import package:flutter_gext_application/nestedRoute/tWidget.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(initialRoute: Main.routeName,getPages: [GetPage(name: Main.routeName, page: () Main()),GetPage(name: SexPage.routeName, page: () SexPage()),GetPage(name: YearPage.routeName, page: () YearPage()),GetPage(name: NamePage.routeName, page: () NamePage()),GetPage(name: SuccessPage.routeName, page: () SuccessPage()),],);} }const int key 1000;class Main extends StatelessWidget {static String routeName /main;overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(身份验证)),body: Navigator(key: Get.nestedKey(key),initialRoute: SexPage.routeName,onGenerateRoute: (settings) {if (settings.name SexPage.routeName) {return GetPageRoute(settings: settings,page: () SexPage(),);} else if (settings.name YearPage.routeName) {return GetPageRoute(settings: settings,page: () YearPage(),);} else if (settings.name NamePage.routeName) {return GetPageRoute(settings: settings,page: () NamePage(),);}return null;},),);} }class SexPage extends StatelessWidget {static String routeName /sex;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(性别男).title,ElevatedButton(onPressed: () {Get.toNamed(YearPage.routeName, id: key);},child: const Text(下一页面),)],),),),);} }class YearPage extends StatelessWidget {static String routeName /year;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(年龄40).title,ElevatedButton(onPressed: () {Get.toNamed(NamePage.routeName, id: key);},child: const Text(下一页面),)],),),),);} }class NamePage extends StatelessWidget {static String routeName /name;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [const Text(姓名高启强).title,ElevatedButton(onPressed: () {Get.toNamed(SuccessPage.routeName);},child: const Text(下一页面),)],),),),);} }class SuccessPage extends StatelessWidget {static String routeName /success;overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: const Text(你是一个人类验证完毕).title,),);} }相关组件 SnakBar Get.snackbar(DOTA2,恭喜中国队夺冠!,backgroundColor: Colors.white,boxShadows: [BoxShadow(color: Colors.black.withAlpha(55),offset: const Offset(1, 1),blurRadius: 2,)],);Dialogs Get.defaultDialog(title: 警告,onConfirm: () {Get.back();},middleText: 这是一个默认的弹窗你知道了吗,);BottomSheets Get.bottomSheet(Wrap(children: Widget[ListTile(leading: const Icon(Icons.music_note),title: const Text(Music),onTap: () {},),ListTile(leading: const Icon(Icons.videocam),title: const Text(Video),onTap: () {},),],),backgroundColor: Colors.white,);ValueBuilder StatefulWidget的简化版 import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return const GetMaterialApp(home: Home(),);} }class Home extends StatelessWidget {const Home({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: ValueBuilderbool?(initialValue: false,builder: (value, updateFn) {return Switch(value: value!,onChanged: (newValue) {updateFn(newValue);},);},onUpdate: (value) print(Value updated: $value),onDispose: () print(dispose),),),);} }ObxValue ValueBuilder的简化版本融入了响应式变量 import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(home: Home(),);} }class Home extends StatelessWidget {final switchValue false.obs;Home({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: ObxValue((data) Switch(value: data.value, onChanged: data.call),switchValue,),),);} }Get Worker ever 每次once 头次debounce 连续变化后的最后那一次interval 间隔t秒后取一次 案例 import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(home: Home(),);} }class Home extends StatelessWidget {final input .obs;final everValue .obs;final onceValue .obs;final debounceValue .obs;final intervalValue .obs;Home({super.key}) {ever(input, (value) {everValue.value value;});once(input, (value) {onceValue.value value;});debounce(input, (value) {debounceValue.value value;});interval(input,(value) {intervalValue.value value;},time: const Duration(seconds: 2),);}overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Obx(() {return Column(mainAxisSize: MainAxisSize.min,children: [ObxValue((data) {return Column(mainAxisSize: MainAxisSize.min,children: [Text(data.value),TextField(onChanged: data.call),],);},input,),Text(ever(每次) - ${everValue.value}),Text(once(首次) - ${onceValue.value}),Text(debounce(防抖) - ${debounceValue.value}),Text(internal(间隔) - ${intervalValue.value}),],);}),),);} } GetView StateMixin GetConnect StateMixin 比如有一个数据它是需要通过网络请求来获取的。那么它有空、获取中、获取成功、获取失败几个状态那么这个StateMixin可以管理这个数据。GetView 个人比较推荐使用这个。它是通过传入泛型来注册ControllerGetConnect 提供数据 案例 获取某一坐标下的天气情况 GetConnect 网络请求获取数据 import package:get/get.dart;class WeatherProvider extends GetConnect {final weatherApi c23bb570c66f248d4543c7480169072b;overridevoid onInit() {super.onInit();httpClient.baseUrl https://api.openweathermap.org;}FutureResponse getWeather(double lat, double lon) {String url /data/2.5/weather?lat$latlon$lonappid$weatherApi;return get(url);} }GetxController with StateMixin 维护WeatherDataModel这个变量 通过GetConnect获取的数据 根据不同的状态返回 分别返回不同的RxStatus import package:get/get.dart;import weather_data_model.dart; import weather_provider.dart;class WeatherController extends GetxController with StateMixinWeatherDataModel {final provider Get.findWeatherProvider();void getWeather() async {final response await provider.getWeather(43.5, 140.5);if (response.hasError) {change(null, status: RxStatus.error(error));} else {final data WeatherDataModel.fromJson(response.body);change(data, status: RxStatus.success());}} }GetView 通过传入泛型WeatherController获取controller。最后通过controller.obx import package:flutter/material.dart; import package:get/get.dart;import binding.dart; import controller.dart;void main() {runApp(App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(home: Main(),initialBinding: Binding(),);} }class Main extends GetViewWeatherController {const Main({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [ElevatedButton(onPressed: () {controller.getWeather();},child: Text(获取数据),),controller.obx((state) {return Text(weather is ${state!.weather!.first.main!});},onLoading: const Text(加载中...),onEmpty: const Text(数据空...),onError: (error) {return const Text(出错...);},),],),),);} }注册依赖及绑定 import package:flutter_gext_application/GetViewGetConnectStateMixin/weather_provider.dart; import package:get/get.dart;import controller.dart;class Binding extends Bindings {overridevoid dependencies() {Get.lazyPut(() WeatherController());Get.lazyPut(() WeatherProvider());} }GetWidget Get.create() 先看案例 案例 Get.lazyput GetView 第一种我采用Get.put 或者Get.lazyput的方式去注册GetxController 配合GetView 无论怎么点这个controller早已注册好了返回的永远都是同一个实例 - Get.create GetWidget 第二种我采用Get.create的方式去注册GetxController 配合GetWidget Get.create 注册的了新的实例 相关的官方文档 大致意思每隔GetWidget都有自己的controller在GetWidget中 你可以放心使用Get.create Get.create会实例一个新的controller。每次调用find都会实例一个新的对象 GetService 可以理解为GetxController的简化版本也有它的生命周期。但是有个特性在项目中总是要通过Get.find来找到它。比如后端提供的接口api存储数据缓存等 这样看来也就知道它为什么名字里带service import package:flutter/material.dart; import package:get/get.dart;void main() async {await initServices();runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return const GetMaterialApp(home: Home());} }class Home extends StatelessWidget {const Home({super.key});overrideWidget build(BuildContext context) {return const Scaffold();} }Futurebool initServices() async {print(starting service ...);await Get.putAsync(() DbService().init());await Get.putAsync(() SettingService().init());print(All services started...);return true; }class DbService extends GetxService {FutureDbService init() async {print($runtimeType delays 2 sec);await 2.delay();print($runtimeType ready!);return this;} }class SettingService extends GetxService {FutureSettingService init() async {print($runtimeType delays 1 sec);await 1.delay();print($runtimeType ready!);return this;} }响应式布局 响应式这件事不止布局还设计各个方面。这里Getx是提供了GetResponsiveView来处理布局上的响应式 GetResponsiveView builder()根据默认返回的屏幕宽度返回一行到底要摆几个方块 class ResponsiveView extends GetResponsiveViewController {overrideWidget builder() {return Scaffold(appBar: AppBar(title: ResponsiveViewSetting()),body: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: screen.responsiveValueint(desktop: 6,tablet: 4,mobile: 2,watch: 1,) ??4,),itemBuilder: (BuildContext context, int index) {return Container(decoration: BoxDecoration(border: Border.all(color: Colors.black.withAlpha(55)),color: Colors.blue.withAlpha(55),),alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Text($content${screen.width}),);},itemCount: 100,),);}String get content screen.screenType ScreenType.Desktop? 桌面: screen.screenType ScreenType.Phone? 手机: screen.screenType ScreenType.Tablet? 平板: screen.screenType ScreenType.Watch? 手表: 无; }alwaysUseBuilder 不使用build()使用另外四个回调返回 ResponsiveScreenSettings 自己定义手机该多宽平板该多宽桌面端该多宽 ResponsiveView(): super(settings: const ResponsiveScreenSettings(desktopChangePoint: 900,tabletChangePoint: 800,watchChangePoint: 500,));运行效果 import package:flutter/material.dart; import package:flutter_gext_application/GetResponsiveView/controller.dart; import package:flutter_gext_application/nestedRoute/main.dart; import package:get/get.dart;class ResponsiveView extends GetResponsiveViewController {// ResponsiveView()// : super(// settings: const ResponsiveScreenSettings(// desktopChangePoint: 900,// tabletChangePoint: 800,// watchChangePoint: 500,// ));overrideWidget builder() {return Scaffold(appBar: AppBar(title: ResponsiveViewSetting()),body: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: screen.responsiveValueint(desktop: 6,tablet: 4,mobile: 2,watch: 1,) ??4,),itemBuilder: (BuildContext context, int index) {return Container(decoration: BoxDecoration(border: Border.all(color: Colors.black.withAlpha(55)),color: Colors.blue.withAlpha(55),),alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Text($content${screen.width}),);},itemCount: 100,),);}String get content screen.screenType ScreenType.Desktop? 桌面: screen.screenType ScreenType.Phone? 手机: screen.screenType ScreenType.Tablet? 平板: screen.screenType ScreenType.Watch? 手表: 无; }class ResponsiveViewSetting extends GetResponsiveViewController {ResponsiveViewSetting({super.key}) : super(alwaysUseBuilder: false);overrideWidget tablet() {return const Text(TABLE).title;}overrideWidget phone() {return const Text(PHONE).title;}overrideWidget desktop() {return const Text(DESKTOP).title;}overrideWidget watch() {return const Text(WATCH).title;} }void main() {runApp(App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return MaterialApp(home: Home(),);} }class Home extends StatelessWidget {const Home({super.key});overrideWidget build(BuildContext context) {return ResponsiveView();} }自定义响应式函数 Getx定义的GetResponsiveView多少有限局限性所以可以自己对上下文做扩展比如根据宽度来决定返回传入的泛型 这样不需要引入getx也能实现响应式 import package:flutter/material.dart;/// 扩展 上下文BuildContext extension Responsive on BuildContext {T responsiveT(T defaultVal, {T? sm,T? md,T? lg,T? xl,}) {final wd MediaQuery.of(this).size.width;return wd 1280? (xl ?? lg ?? md ?? sm ?? defaultVal): wd 1024? (lg ?? md ?? sm ?? defaultVal): wd 768? (md ?? sm ?? defaultVal): wd 640? (sm ?? defaultVal): defaultVal;} }import package:flutter/material.dart; import package:flutter_gext_application/GetResponsiveView/context.dart;class ResponsiveView extends StatelessWidget {const ResponsiveView({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:context.responsiveint(1, sm: 2, md: 3, lg: 4, xl: 5),),itemBuilder: (BuildContext context, int index) {double width MediaQuery.of(context).size.width;return Container(decoration: BoxDecoration(border: Border.all(color: Colors.black.withAlpha(55)),color: Colors.blue.withAlpha(55),),alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Text($width),);},itemCount: 100,),);} }主题切换 import package:flutter/material.dart; import package:get/get.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return const GetMaterialApp(home: Home());} }class Home extends StatelessWidget {const Home({super.key});overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(主题),),body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [Text(是否为黑色主题${Get.isDarkMode}),ElevatedButton(onPressed: () {Get.changeTheme(Get.isDarkMode ? ThemeData.light() : ThemeData.dark());},child: const Text(dark theme),)],),),);} }国际化语言翻译 首先需要一个Translation import package:flutter/material.dart; import package:get/get.dart;import keys.dart; import str_translations.dart;void main() {runApp(const App()); }class App extends StatelessWidget {const App({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(locale: Locale(StrTranslation.zhCNKey),translations: StrTranslation(),home: const Home(),);} }class Home extends StatelessWidget {const Home({super.key});overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisSize: MainAxisSize.min,children: [Text(SR.testTranslation.tr,style: const TextStyle(fontSize: 20),),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ElevatedButton(onPressed: () {Get.updateLocale(Locale(StrTranslation.zhCNKey));},child: const Text(中文),),ElevatedButton(onPressed: () {Get.updateLocale(Locale(StrTranslation.enUSKey));},child: const Text(英文),)],),],),),);} }import package:flutter_gext_application/lan/en.dart; import package:flutter_gext_application/lan/zh.dart; import package:get/get.dart;class StrTranslation extends Translations {static String zhCNKey zh_CN;static String enUSKey en_US;overrideMapString, MapString, String get keys {return {zhCNKey: zh,enUSKey: en,};} }import keys.dart;const zh {SR.testTranslation: 好久不见你还好吗, };import keys.dart;const en {SR.testTranslation: Long time no see, are you okay, };class SR {static const String testTranslation testTranslation; }运行 利用插件生成模板代码 挺好用的插件 更多API 建议直接看这个文档 他喵的终于写完了 点个关注呗
http://www.zqtcl.cn/news/265025/

相关文章:

  • 汽车维修保养网站模板北京网站建设知名公司排名
  • 网站建设案例分享网络推广网
  • 广州知名网站推广app软件开发制作公司电话
  • 泉州专业网站建设seo是指什么职位
  • 怎么做房产网站张家港高端网站制作
  • 做网站运营公司收费广东短视频seo搜索哪家好
  • 外贸网站 源码做的好详情页网站
  • 冀州网站制作邢台百姓网官网
  • 佛山做外贸网站方案自助网站推广系统
  • 安徽鸿顺鑫城建设集团网站小区物业管理网站开发报告
  • 有关网站建设文章常熟做网站多少钱
  • 网站流量报表江苏住房和城乡建设厅网站
  • 提供做网站公司有哪些个人建网站的费用
  • 网站后台添加表格wordpress垂直分页导航插件
  • 重庆网站建设有限公司六安市裕安区建设局网站
  • 北京产品网站建设如何做移动支付网站
  • 做同城购物网站赚钱吗设计企业网站流程
  • 网站要用什么软件做建设工程施工合同专属管辖
  • 模板网站建设制作佛山正规网站建设哪家好
  • 飞虎队网站建设网络公司起名大全
  • 如何发布自己的网站视频8首页制作代码
  • 网站开发实用案例教程普陀网站制作
  • 建一个网站需要哪些知识招远网站建设
  • 文章标题-栏目名称-网站名 dede环保网站设计建设论文
  • centos wordpress建站北京专门做网站的
  • wordpress网站的彻底清理百度网站联系方式
  • 网站建设签收单网页制作模板的作用
  • 已购买域名 如何做网站网络规划设计师通过率多少
  • 酒店网站建设需求分析wordpress iis
  • 烟台网站建设服务新钥匙网站建设