饭宝 发表于 2024-8-23 04:54:42

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



目录
前言

一.安装
二.从一个计时器开始
三.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工程的时候,体系会天生一个计时器的示例代码,代码大致如下(我删除了部分解释代码):
import 'package:flutter/material.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
      colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
    setState(() {
      _counter++;
    });
}

@override
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      title: Text(widget.title),
      ),
      body: Center(
      child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
            'You have pushed the button this many times:',
            ),
            Text(
            '$_counter',
            style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
      ),
      ),
      floatingActionButton: FloatingActionButton(
      onPressed: _incrementCounter,
      tooltip: 'Increment',
      child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
}
}
        主要功能是点击+按钮,每次计时器的个数+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,节流下内存。
        修改之后的完整代码如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
      colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
}
}
class Controller extends GetxController{
var counter = 0.obs;
incrementCounter()=>counter++;
}

class MyHomePage extends StatelessWidget {
const MyHomePage({super.key, required this.title});
final String title;

@override
Widget build(BuildContext context) {
    final Controller controller = Get.put(Controller());

    return Scaffold(
      appBar: AppBar(
      backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      title: Text(title),
      ),
      body: Center(
      child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
            'You have pushed the button this many times:',
            ),
            Obx(() => Text(
            '${controller.counter}',
            style: Theme.of(context).textTheme.headlineMedium,
            )),
          ],
      ),
      ),
      floatingActionButton: FloatingActionButton(
      onPressed: (){
          controller.incrementCounter();
      },
      tooltip: 'Increment',
      child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
}
}
        代码运行之后的效果如如下:
https://i-blog.csdnimg.cn/blog_migrate/1f3f669110f20399e1a7f2845b65dc54.gif
图1.计时器
三.Getx路由管理

1.平凡路由导航

1.导航到新的页面

        如果我们有一个新页面NextScreenPage,代码如下:
import 'package:flutter/material.dart';

class NextScreenPage extends StatelessWidget {
const NextScreenPage({super.key});

@override
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      title: const Text("新页面"),
      ),
      body: Container(
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
}
}         效果图如下:
https://i-blog.csdnimg.cn/blog_migrate/583e323cf0d7d54f14ee4788dcc9366e.gif
        图2.跳转新页面  
2.返回上一页

        照旧以上面的代码为例,我们添加一个返回按钮,点击返回按钮的时候,回到当前页面。主必要在按钮的点击变乱中添加如下代码即可:
   Get.back();
https://i-blog.csdnimg.cn/blog_migrate/4b0e427c9450de02d633d62273709814.gif
       图3.返回上一页
        NextScreenPage页面完整代码如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class NextScreenPage extends StatelessWidget {
const NextScreenPage({super.key});

@override
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      title: const Text("新页面"),
      ),
      body: Center(
      child: ElevatedButton(onPressed: (){
          Get.back();
      }, child: const Text("返回上一个页面")),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
}
} 3.进入下一个页面,但没有返回上一个页面的选项

         我们利用下面的代码跳转。
   Get.off(()=>const FirstPage());
        如下图所示,当我们点击第三个按钮之后,进入到First页面。
        但是我们点击FirstPage的返回按钮,直接回到了首页。
       
https://i-blog.csdnimg.cn/blog_migrate/c27a8b781b532116ac332d947f8974b6.gif
       图4.导航并销毁前页面页面
                这种场景用于SplashScreens,登录页面等。比方我们登陆完成之后,进入到某个页面,在某个页面点击返回的时候,返回到项目主页。
4.进入下一个界面并取消之前的全部路由

   Get.offAll(() => const ThirdPage());
        效果图如下:
https://i-blog.csdnimg.cn/blog_migrate/b515f11dfa1fb9a1b26eb8bec65345c4.gif
图5.导航到下一个页面并取消全部路由
5.导航并接收会传值

        假设我们点击跳转按钮之后跳转到DetailPage,按钮的点击变乱中我们利用下面的代码获取DetailPage回传的值:
   var data = await Get.to(()=>const DetailPage());
Get.snackbar('Hi', '下一个页面传回来的值: $data');
  
        DetailPage页面代码如下:
import 'package:flutter/material.dart';

class DetailPage extends StatelessWidget {
const DetailPage({super.key});

@override
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      title: const Text('Detail页面'),
      ),
      body: Center(
      child: FilledButton(
          onPressed: () {
            Navigator.pop(context, '返回的数据');
          },
          child: const Text('返回'),
      ),
      ),
    );
}
}        运行效果图下:跳转到下一个页面返回之后并利用snackbar表现。
        运行效果图如下:
https://i-blog.csdnimg.cn/blog_migrate/3f6e2a9956e969c95fed522d320bc98b.gif
        图6.导航并接收下一个页面返回值
2.别名路由导航

        Get支持别名路由,利用别名路由的时候,我们必要在GetMaterialApp定义一下,如果我们有一个NextScreenPage页面,利用别名路由的时候,代码定义如下:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      initialRoute: "/",
      getPages: [
      GetPage(name: "/next_screen", page: ()=>const NextScreenPage()),
      ],
      theme: ThemeData(
      colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
}
} 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');
https://i-blog.csdnimg.cn/blog_migrate/5d93aa9f6052a576cb4ef7e17d400825.gif
        图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"
);
https://i-blog.csdnimg.cn/blog_migrate/816fdaa14e206cdac44e513501c9eed2.gif
        图8.免dialogs导航
3.BottomSheets

        Get.bottomSheet雷同于showModalBottomSheet,但不必要context:
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: () {},
),
],
)
);         效果图如下:
https://i-blog.csdnimg.cn/blog_migrate/672a510b8bcd199a656cfca6541b6c9c.gif
图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企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Flutter中GetX的用法(超详细利用指南之路由管理篇)