【Flutter】Getx上篇

🔥 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:Flutter学习
🌠 首发时间:2024年5月30日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾

状态管理

通俗地讲:当我们想在多个界面(组件 / Widget)之间共享状态(数据),或者一个页面(组件 / Widget)中的多个子组件之间共享状态(数据),这个时候我们就可以用 Flutter 中的状态管理来管理统一的状态(数据),实现不同组件之间的传值和数据共享。

现在 Flutter 的状态管理方案很多,如 reduxblocstateproviderGetx 等。

provider 是官方提供的状态管理解决方案,主要功能就是状态管理。而 Getx 是第三方的状态管理插件,不仅具有状态管理的功能,还具有路由管理、主题管理、国际化多语言管理、Obx 局部更新、网络请求、数据验证等功能,相比于其它状态管理插件,Getx 更简单、功能强大并且高性能。

Getx介绍

GetXFlutter 上的一个轻量且强大的解决方案,Getx 为我们提供了高性能的状态管理、智能的依赖注入和便捷的路由管理。

  • GetX3 个基本原则:

    • 性能GetX 专注于性能和最小资源消耗。GetX 打包后的 apk 占用大小和运行时的内存占用与其他状态管理插件不相上下
    • 效率Getx 的语法非常简捷,并保持了极高的性能,能极大缩短你的开发时长
    • 结构GetX 可以将界面、逻辑、依赖和路由完全解耦,用起来更清爽,逻辑更清晰,代码更容易维护
  • GetX 并不臃肿,却很轻量。如果你只使用状态管理,只有状态管理模块会被编译,其他没用到的东西都不会被编译到你的代码中。它拥有众多的功能,但这些功能都在独立的容器中,只有在使用后才会启动。

  • Getx 有一个庞大的生态系统,能够在 AndroidiOSWebMacLinuxWindows 和你的服务器上用同样的代码运行。 通过 Get server 可以在你的后端完全重用你在前端写的代码。

  • 官网:https://pub-web.flutter-io.cn/packages/get

    在这里插入图片描述

  • 中文文档:https://github.com/jonataslaw/getx/blob/master/README.zh-cn.md

    在这里插入图片描述

Getx中的Dialog以及改变主题

Getx安装

引入依赖:

dependencies:
  get: ^4.6.6

在需要用到的文件中导入,它将被使用:

import 'package:get/get.dart';

defaultDialog组件

GetX 框架中,defaultDialog是用于显示对话框的默认方法。它有以下参数:

  1. title:对话框的标题(可选)

    • 用于显示在对话框顶部的标题文本。
    • 默认值为 null,表示不显示标题。
  2. content:对话框的内容(可选)

    • 存储在对话框中间的信息。
    • 可以是一个文本字符串或一个 Widget。
    • 默认值为 null,表示不显示内容。
  3. textConfirm:确认按钮的文本(可选)

    • 用于在确认按钮上显示的文本。
    • 默认值为 "OK"
  4. textCancel:取消按钮的文本(可选)

    • 用于在取消按钮上显示的文本。
    • 默认值为 "Cancel"
  5. confirmTextColor:确认按钮文本的颜色(可选)

    • 确认按钮上文本的颜色。
    • 可以是一个颜色字符串或一个颜色对象。
    • 默认值为 null,使用平台默认颜色。
  6. cancelTextColor:取消按钮文本的颜色(可选)

    • 取消按钮上文本的颜色。
    • 可以是一个颜色字符串或一个颜色对象。
    • 默认值为 null,使用平台默认颜色。
  7. barrierDismissible:是否允许通过点击对话框外部来关闭对话框(可选)

    • 如果设置为 true,则用户可以通过点击对话框外部来关闭它。
    • 如果设置为 false,则用户必须点击确认或取消按钮才能关闭对话框。
    • 默认值为 true
  8. onConfirm:确认按钮被点击时的回调函数(可选)

    • 当用户点击确认按钮时调用的回调函数。
    • 如果没有提供,则表示不需要处理确认事件。
  9. onCancel:取消按钮被点击时的回调函数(可选)

    • 当用户点击取消按钮时调用的回调函数。
    • 如果没有提供,则表示不需要处理取消事件。
import 'package:flutter/material.dart';
import 'package:get/get.dart'; //导入

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

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

  
  Widget build(BuildContext context) {
    //改为使用GetMaterialApp
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  //Flutter默认的dialog, 代码繁杂
  void _alertDialog(context) async {
    await showDialog(
      barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框
      context: context,
      builder: (context) {
        return AlertDialog(
          title: const Text("提示信息!"),
          content: const Text("您确定要删除吗"),
          actions: [
            TextButton(
                onPressed: () {
                  Navigator.of(context)
                      .pop("确定"); //点击按钮让AlertDialog消失, 同时返回“确定”
                },
                child: const Text("确定")),
            TextButton(
                onPressed: () {
                  Navigator.of(context).pop("取消");
                },
                child: const Text("取消"))
          ],
        );
      },
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Getx'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                _alertDialog(context);
              },
              child: const Text('Flutter默认的dialog'),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                //Getx对dialog进行了封装
                Get.defaultDialog(
                  title: "提示信息!",
                  middleText: "您确定要删除吗?",
                  confirm: ElevatedButton(
                    onPressed: () {
                      Get.back(); //Getx对路由也进行了封装
                    },
                    child: const Text("确定"),
                  ),
                  cancel: ElevatedButton(
                    onPressed: () {
                      Get.back();
                    },
                    child: const Text("取消"),
                  ),
                );
              },
              child: const Text('Getx的defaultDialog'),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {},
              child: const Text('Getx的snackbar'),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {},
              child: const Text('Getx bottomSheet切换主题'),
            ),
          ],
        ),
      ),
    );
  }
}

在这里插入图片描述

snackbar组件

Snackbar 和我们前面讲的 toast 有点相似,如果想在应用程序中触发某些特定的事件后,需要弹出快捷消息,那么使用 snackbar 则是最佳的选择。

我们可以通过 Get.snackbar() 来显示 snackbar,如下所示

ElevatedButton(
  onPressed: () {
    Get.snackbar(
      "提示",
      "你有一条新的信息",
      backgroundColor: Colors.blue[200],
      colorText: Colors.white,
      snackPosition: SnackPosition.TOP,
    );
  },
  child: const Text('Getx的snackbar'),
),

在这里插入图片描述

Getx bottomSheet切换主题

ElevatedButton(
  onPressed: () {
    Get.bottomSheet(Container(
      color: Get.isDarkMode ? Colors.black : Colors.white,
      height: 200,
      child: Column(
        children: [
          ListTile(
            leading: Icon(
              Icons.wb_sunny_outlined,
              color: Get.isDarkMode ? Colors.white : Colors.black,
            ),
            onTap: () {
              Get.changeTheme(ThemeData.light());
              Get.back();
            },
            title: Text(
              "白天模式",
              style: TextStyle(
                color: Get.isDarkMode ? Colors.white : Colors.black,
              ),
            ),
          ),
          ListTile(
            leading: Icon(
              Icons.wb_sunny,
              color: Get.isDarkMode ? Colors.white : Colors.black,
            ),
            onTap: () {
              Get.changeTheme(ThemeData.dark());
              Get.back();
            },
            title: Text(
              "黑夜模式",
              style: TextStyle(
                color: Get.isDarkMode ? Colors.white : Colors.black,
              ),
            ),
          )
        ],
      ),
    ));
  },
  child: const Text('Getx bottomSheet切换主题'),
),

在这里插入图片描述

在这里插入图片描述

Getx路由管理

Getx 为我们封装了 Navigation,无需 context 可进行跳转,使用 Getx 进行路由跳转非常的简单,只需要调用 Get.to() 即可进行路由跳转, Getx 路由跳转简化了跳转动画设置、动画时长定义、动画曲线设置。

Get.to()实现普通路由跳转

ps:需要引入跳转页面的组件

Get.to(() => Nextscreen());

Get.toNamed()跳转到其它页面

Get.toNamed("/login");

Get.toNamed("/shop", arguments: {
	"id": 20,
});

Get.back()返回到上一级页面

Get.back();

Get.offAI()返回到根

ps:需要引入根页面的组件

Get.offAll(const Tabs(index: 4));

Get.off(Nextscreen())

进入下一个页面,但没有返回上一个页面的选项(用于闪屏页,登录页面等)

ps:需要引入跳转页面的组件

Get.off(Nextscreen());

defaultTransition可以配置默认动画

通过设置 GetMaterialApp 的参数 defaultTransition,可以配置页面跳转的默认动画。

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

  
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      initialRoute: "/",
      defaultTransition: Transition.rightToLeft,
    );
  }
}

GetPage 可以配置动态路由

通过 getPages 参数来配置动态路由

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

  
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      initialRoute: "/",
      defaultTransition: Transition.rightToLeft,
      getPages: [
        GetPage(name: "/", page: () => const Tabs()),
        GetPage(
          name: "/login",
          page: () => const LoginPage(),
          transition: Transition.circularReveal, //也可以单独配置页面的跳转动画
        ),
      ],
    );
  }
}

Getx 路由跳转传值以及接受数据

  1. 路由配置中不需要再传参

  2. 跳转传值不变:

    Get.toNamed("/shop", arguments: {
    	"id":20
    });
    
  3. 在跳转的页面中,我们只需要通过 Get.arguments 即可接收到数据

将路由抽离

router.dart

import 'package:get/get.dart';
import '../pages/tabs/home.dart';
import '../pages/tabs.dart';

class AppPage {
  static final routes = [
    GetPage(name: "/", page: () => const Tabs()),
    GetPage(
      name: "/home",
      page: () => const HomePage(),
      transition: Transition.circularReveal, //也可以单独配置页面的跳转动画
    ),
  ];
}

main.dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import './routers/router.dart';

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

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

  
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      initialRoute: "/",
      defaultTransition: Transition.rightToLeft,
      getPages: AppPage.routes,
    );
  }
}

Getx 中间件配置

GetX 框架中,中间件(Middleware)是一种机制,可以让开发者在页面路由、导航等过程中添加额外的逻辑处理。中间件能够拦截并处理路由跳转、导航事件等,为应用程序提供更多的灵活性和控制。

GetX 框架中,中间件可以用来执行诸如日志记录、权限检查、数据加载等操作。通过中间件,你可以在页面跳转前后、导航事件触发时执行特定的逻辑,而无需直接修改页面代码。

比如,我们自己写一个中间件

import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';

class HomeMiddleware extends GetMiddleware {
  
  RouteSettings? redirect(String? route) {
    print(route);
    // return null; //表示不做任何操作, 跳转到以前的路由
    return const RouteSettings(name: "/category", arguments: {}); //跳转到对应的页面
  }
}

GetPage 中可以配置中间件

import 'package:get/get.dart';
import '../middleware/homeMiddleware.dart';
import '../pages/tabs/category.dart';
import '../pages/tabs/home.dart';
import '../pages/tabs.dart';

class AppPage {
  static final routes = [
    GetPage(name: "/", page: () => const Tabs()),
    GetPage(
      name: "/home",
      page: () => const HomePage(),
      transition: Transition.circularReveal, //也可以单独配置页面的跳转动画
      middlewares: [HomeMiddleware()], //中间件
    ),
    GetPage(name: "/category", page: () => const CategoryPage()),
  ];
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序喵正在路上

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值