Flutter中GetX的用法(超详细利用指南之路由管理篇)

饭宝  论坛元老 | 2024-8-23 04:54:42 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1038|帖子 1038|积分 3114

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x


目录
前言

一.安装
二.从一个计时器开始
三.Getx路由管理
1.平凡路由导航
1.导航到新的页面
2.返回上一页
3.进入下一个页面,但没有返回上一个页面的选项
4.进入下一个界面并取消之前的全部路由
5.导航并接收会传值
2.别名路由导航
1.导航到下一个页面
2.浏览并删除前一个页面
3.浏览并删除全部以前的页面
4.未定义导航
5.别名路由传值
6.动态网页链接
3.中间件
4.免context导航
1.SnackBars
2.Dialogs
3.BottomSheets


前言



        正如Get官方先容,GetX 是 Flutter 上的一个轻量且强大的办理方案:高性能的状态管理、智能的依赖注入和便捷的路由管理。GetX 有3个根本原则:
        性能: GetX 专注于性能和最小资源消耗。
        效率: GetX 的语法非常简捷,并保持了极高的性能,能极大缩短你的开发时长。
        结构: GetX 可以将界面、逻辑、依赖和路由之间低耦合,逻辑更清楚,代码更容易维护。
        这篇文章主要是先容下GetX的用法。
一.安装

        现在get最新的版本是4.6.6。安装方式如下:
   dependencies:
  get: ^4.6.6
  二.从一个计时器开始

        但我们创建一个flutter工程的时候,体系会天生一个计时器的示例代码,代码大致如下(我删除了部分解释代码):
  1. import 'package:flutter/material.dart';
  2. void main() {
  3.   runApp(const MyApp());
  4. }
  5. class MyApp extends StatelessWidget {
  6.   const MyApp({super.key});
  7.   @override
  8.   Widget build(BuildContext context) {
  9.     return MaterialApp(
  10.       title: 'Flutter Demo',
  11.       theme: ThemeData(
  12.         colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
  13.         useMaterial3: true,
  14.       ),
  15.       home: const MyHomePage(title: 'Flutter Demo Home Page'),
  16.     );
  17.   }
  18. }
  19. class MyHomePage extends StatefulWidget {
  20.   const MyHomePage({super.key, required this.title});
  21.   final String title;
  22.   @override
  23.   State<MyHomePage> createState() => _MyHomePageState();
  24. }
  25. class _MyHomePageState extends State<MyHomePage> {
  26.   int _counter = 0;
  27.   void _incrementCounter() {
  28.     setState(() {
  29.       _counter++;
  30.     });
  31.   }
  32.   @override
  33.   Widget build(BuildContext context) {
  34.     return Scaffold(
  35.       appBar: AppBar(
  36.         backgroundColor: Theme.of(context).colorScheme.inversePrimary,
  37.         title: Text(widget.title),
  38.       ),
  39.       body: Center(
  40.         child: Column(
  41.           mainAxisAlignment: MainAxisAlignment.center,
  42.           children: <Widget>[
  43.             const Text(
  44.               'You have pushed the button this many times:',
  45.             ),
  46.             Text(
  47.               '$_counter',
  48.               style: Theme.of(context).textTheme.headlineMedium,
  49.             ),
  50.           ],
  51.         ),
  52.       ),
  53.       floatingActionButton: FloatingActionButton(
  54.         onPressed: _incrementCounter,
  55.         tooltip: 'Increment',
  56.         child: const Icon(Icons.add),
  57.       ), // This trailing comma makes auto-formatting nicer for build methods.
  58.     );
  59.   }
  60. }
复制代码
        主要功能是点击+按钮,每次计时器的个数+1.点击按钮之后,调用setState方法革新_counter变量。
        下面我们看一下如何利用getx来实现上述的功能:
        第一步:把体系的MaterialApp改成GetMaterialApp:
   void main() => runApp(GetMaterialApp(home: Home()));
          第二步:创建业务类,我们把_counter变量放在Controller类中:
   class Controller extends GetxController{
  var counter = 0.obs;
  increment() => counter++;
}
          第三步:利用StatelessWidget取代StatefulWidget,节流下内存。
        修改之后的完整代码如下:
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. void main() {
  4.   runApp(const MyApp());
  5. }
  6. class MyApp extends StatelessWidget {
  7.   const MyApp({super.key});
  8.   @override
  9.   Widget build(BuildContext context) {
  10.     return GetMaterialApp(
  11.       title: 'Flutter Demo',
  12.       theme: ThemeData(
  13.         colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
  14.         useMaterial3: true,
  15.       ),
  16.       home: const MyHomePage(title: 'Flutter Demo Home Page'),
  17.     );
  18.   }
  19. }
  20. class Controller extends GetxController{
  21.   var counter = 0.obs;
  22.   incrementCounter()=>counter++;
  23. }
  24. class MyHomePage extends StatelessWidget {
  25.   const MyHomePage({super.key, required this.title});
  26.   final String title;
  27.   @override
  28.   Widget build(BuildContext context) {
  29.     final Controller controller = Get.put(Controller());
  30.     return Scaffold(
  31.       appBar: AppBar(
  32.         backgroundColor: Theme.of(context).colorScheme.inversePrimary,
  33.         title: Text(title),
  34.       ),
  35.       body: Center(
  36.         child: Column(
  37.           mainAxisAlignment: MainAxisAlignment.center,
  38.           children: <Widget>[
  39.             const Text(
  40.               'You have pushed the button this many times:',
  41.             ),
  42.             Obx(() => Text(
  43.               '${controller.counter}',
  44.               style: Theme.of(context).textTheme.headlineMedium,
  45.             )),
  46.           ],
  47.         ),
  48.       ),
  49.       floatingActionButton: FloatingActionButton(
  50.         onPressed: (){
  51.           controller.incrementCounter();
  52.         },
  53.         tooltip: 'Increment',
  54.         child: const Icon(Icons.add),
  55.       ), // This trailing comma makes auto-formatting nicer for build methods.
  56.     );
  57.   }
  58. }
复制代码
        代码运行之后的效果如如下:

图1.计时器

三.Getx路由管理

1.平凡路由导航

1.导航到新的页面

        如果我们有一个新页面NextScreenPage,代码如下:
  1. import 'package:flutter/material.dart';
  2. class NextScreenPage extends StatelessWidget {
  3.   const NextScreenPage({super.key});
  4.   
  5.   @override
  6.   Widget build(BuildContext context) {
  7.     return Scaffold(
  8.       appBar: AppBar(
  9.         backgroundColor: Theme.of(context).colorScheme.inversePrimary,
  10.         title: const Text("新页面"),
  11.       ),
  12.       body: Container(
  13.       ), // This trailing comma makes auto-formatting nicer for build methods.
  14.     );
  15.   }
  16. }
复制代码
        效果图如下:

        图2.跳转新页面  

2.返回上一页

        照旧以上面的代码为例,我们添加一个返回按钮,点击返回按钮的时候,回到当前页面。主必要在按钮的点击变乱中添加如下代码即可:
   Get.back();
  

       图3.返回上一页

        NextScreenPage页面完整代码如下:
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. class NextScreenPage extends StatelessWidget {
  4.   const NextScreenPage({super.key});
  5.   @override
  6.   Widget build(BuildContext context) {
  7.     return Scaffold(
  8.       appBar: AppBar(
  9.         backgroundColor: Theme.of(context).colorScheme.inversePrimary,
  10.         title: const Text("新页面"),
  11.       ),
  12.       body: Center(
  13.         child: ElevatedButton(onPressed: (){
  14.           Get.back();
  15.         }, child: const Text("返回上一个页面")),
  16.       ), // This trailing comma makes auto-formatting nicer for build methods.
  17.     );
  18.   }
  19. }
复制代码
3.进入下一个页面,但没有返回上一个页面的选项

         我们利用下面的代码跳转。
   Get.off(()=>const FirstPage());
          如下图所示,当我们点击第三个按钮之后,进入到First页面。
        但是我们点击FirstPage的返回按钮,直接回到了首页。
       

       图4.导航并销毁前页面页面

                这种场景用于SplashScreens,登录页面等。比方我们登陆完成之后,进入到某个页面,在某个页面点击返回的时候,返回到项目主页。
4.进入下一个界面并取消之前的全部路由

   Get.offAll(() => const ThirdPage());
          效果图如下:

图5.导航到下一个页面并取消全部路由

5.导航并接收会传值

        假设我们点击跳转按钮之后跳转到DetailPage,按钮的点击变乱中我们利用下面的代码获取DetailPage回传的值:
   var data = await Get.to(()=>const DetailPage());
  Get.snackbar('Hi', '下一个页面传回来的值: $data');
    
          DetailPage页面代码如下:
  1. import 'package:flutter/material.dart';
  2. class DetailPage extends StatelessWidget {
  3.   const DetailPage({super.key});
  4.   @override
  5.   Widget build(BuildContext context) {
  6.     return Scaffold(
  7.       appBar: AppBar(
  8.         title: const Text('Detail页面'),
  9.       ),
  10.       body: Center(
  11.         child: FilledButton(
  12.           onPressed: () {
  13.             Navigator.pop(context, '返回的数据');
  14.           },
  15.           child: const Text('返回'),
  16.         ),
  17.       ),
  18.     );
  19.   }
  20. }
复制代码
       运行效果图下:跳转到下一个页面返回之后并利用snackbar表现。
        运行效果图如下:

        图6.导航并接收下一个页面返回值

2.别名路由导航

        Get支持别名路由,利用别名路由的时候,我们必要在GetMaterialApp定义一下,如果我们有一个NextScreenPage页面,利用别名路由的时候,代码定义如下:
  1. class MyApp extends StatelessWidget {
  2.   const MyApp({super.key});
  3.   @override
  4.   Widget build(BuildContext context) {
  5.     return GetMaterialApp(
  6.       title: 'Flutter Demo',
  7.       initialRoute: "/",
  8.       getPages: [
  9.         GetPage(name: "/next_screen", page: ()=>const NextScreenPage()),
  10.       ],
  11.       theme: ThemeData(
  12.         colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
  13.         useMaterial3: true,
  14.       ),
  15.       home: const MyHomePage(title: 'Flutter Demo Home Page'),
  16.     );
  17.   }
  18. }
复制代码
1.导航到下一个页面

   Get.toNamed("/next_screen");
  2.浏览并删除前一个页面

   Get.offNamed("/next_screen");
  3.浏览并删除全部以前的页面

   Get.offAllNamed("/next_screen");
  4.未定义导航

        为了防止我们导航到未定义的页面,我们可以在GetMaterialApp中定义unknownRoute页面。
   void main() {
  runApp(
    GetMaterialApp(
      unknownRoute: GetPage(name: '/notfound', page: () => UnknownRoutePage()),
      initialRoute: '/',
      getPages: [
        GetPage(name: '/', page: () => MyHomePage()),
        GetPage(name: '/second', page: () => Second()),
      ],
    )
  );
}
  5.别名路由传值

        通过argument通报参数,argument接收字符串、Map、List、类的实例。
   Get.toNamed("/rename_main",arguments: "Getx route manager");
          另一个页面接收值代码如下:
   print(Get.arguments);
//print out: Get is the best
  6.动态网页链接

        Get提供高级动态URL,就像在Web上一样。
   Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");
          第二个页面获取数据:
   debugPrint("id = ${Get.parameters['id']} ");
debugPrint("device = ${Get.parameters['device']} ");
debugPrint("name = ${Get.parameters['name']} ");
  3.中间件

        受制于文章篇幅,这里专门写了一篇Getx鉴权的博客,有爱好的同学们可以查看下。
4.免context导航

        利用GetX我们可以制止利用Flutter非常多的代码去实现SnackBar、Dialogs、BottomSheets。
        下面我们看具体的用法:
1.SnackBars

        GetX创建一个SnackBars代码如下:
   Get.snackbar('SnackBar', '我是SnackBar');
  

        图7.Getx免context导航

        OK,就这么一行代码,我们就轻松的实现了SnackBar。
        我们看看Flutter怎么实现这个功能:
        用Flutter创建一个简朴的SnackBar,你必须获得Scaffold的context,或者你必须利用一个GlobalKey附加到你的Scaffold上。
   final snackBar = SnackBar(
  content: Text('Hi!'),
  action: SnackBarAction(
    label: 'I am a old and ugly snackbar ',
    onPressed: (){}
  ),
);
// 在小组件树中找到脚手架并利用它表现一个SnackBars。
Scaffold.of(context).showSnackBar(snackBar);
          这么一对比,看看Getx提高了多少效率。
        当然这里仅仅是演示getX的用法,具体利用SnackBar的定制,您可以看一下它的源码。
2.Dialogs

        同样我们利用defaultDialog和dialog也不必要context。
        仅仅必要一行代码即可。
        打开Dialogs:
   Get.dialog(YourDialogWidget());
          打开默认Dialogs代码如下:
   Get.defaultDialog(
onConfirm: () => debugPrint("Ok"),
middleText: "我是Dialog"
);
  

        图8.免dialogs导航

3.BottomSheets

        Get.bottomSheet雷同于showModalBottomSheet,但不必要context:
  1. Get.bottomSheet(
  2. Wrap(
  3. children: <Widget>[
  4. ListTile(
  5. leading: const Icon(Icons.music_note),
  6. title: const Text('Music'),
  7. onTap: () {}
  8. ),
  9. ListTile(
  10. leading: const Icon(Icons.videocam),
  11. title: const Text('Video'),
  12. onTap: () {},
  13. ),
  14. ],
  15. )
  16. );
复制代码
        效果图如下:

图9.免BottomSheets导航

5.嵌套导航
        Get让Flutter的嵌套导航更加简朴。 你不必要context,而是通过Id找到你的导航栈。
   Navigator(
  key: Get.nestedKey(1), // create a key by index
  initialRoute: '/',
  onGenerateRoute: (settings) {
    if (settings.name == '/') {
      return GetPageRoute(
        page: () => Scaffold(
          appBar: AppBar(
            title: Text("Main"),
          ),
          body: Center(
            child: TextButton(
              color: Colors.blue,
              onPressed: () {
                Get.toNamed('/second', id:1); // navigate by your nested route by index
              },
              child: Text("Go to second"),
            ),
          ),
        ),
      );
    } else if (settings.name == '/second') {
      return GetPageRoute(
        page: () => Center(
          child: Scaffold(
            appBar: AppBar(
              title: Text("Main"),
            ),
            body: Center(
              child:  Text("second")
            ),
          ),
        ),
      );
    }
  }
),

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

饭宝

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表