Flutter 系列之GetX的学习(2) --> 路由导航

282 阅读3分钟

1. 前言

在上篇文章我们介绍一下getx的概念, 以及如何使用Getx创建我们的Controller控制器,,并且在UI部分进行控制器的实例化,使用GetBuilder进行状态的展示和更新.

那么在本小节我们将介绍Getx的另外一个功能 -->路由导航

2. 基本导航操作

我们新建一个页面, 并使用stl快速搭建出来article下的index.dart的页面模板

在index.dart文件开始输入s t l , 就可以快速填充模板, 类似html文件的!一样

image.png

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('文章'),
        leading: IconButton(onPressed: () {}, icon: const Icon(Icons.arrow_back_ios)),
      ),
      body: const Center(
        child: Text('文章页面'),
      ),
    );
  }
}

紧接着我们需要在counter_screen 里面进行第二个按钮的事件绑定. 核心:Get.to(Article())

  GestureDetector(onTap: () {Get.to(Article());}, child: _buildContainer("跳转文章页面")),

此时我们允许,并且点击, 不出意外的话还是出意外了

image.png

通过阅读报错,我们发现如果想使用这种路由,必须改变我们MaterialAppGetMaterialApp.然后就可以了进行跳转了

ezgif-1-d32dbe30d4.gif

为了方便返回,我们在二级页面添加返回路由的处理

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('文章'),
        leading: IconButton(
            onPressed: () { Get.back();},
            icon: const Icon(Icons.arrow_back_ios)),
      ),
      body: const Center(
        child: Text('文章页面'),
      ),
    );
  }
}

这样通过简单的几步我们就实现了 前进和回退

3. 命名路由

Get.toNamed("/page2");

不过需要提前定义好路由关系表映射关系.

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialRoute: "/",
      getPages: [
            GetPage(name: "/", page: () => const Page1()),
            GetPage(name: "/page1", page: ()=> const Page1()),
            GetPage(name: "/page2", page: ()=> const Page2()),
            GetPage(name: "/page3", page: ()=> const Page3()),
            GetPage(name: "/page4", page: ()=> const Page4()),
      ];,
      title: 'Animated Notch Bottom Bar',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

4. 未定义路由重定向

要处理到未定义路线的导航(404错误),可以在GetMaterialApp中定义unknownRoute页面。

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialRoute: "/",
      // 路由映射表匹配不到就会走这个
      unknownRoute: GetPage(name: "/notfound", page: ()=> NotFound()), 
      getPages: [
            GetPage(name: "/", page: () => const Page1()),
            GetPage(name: "/page1", page: ()=> const Page1()),
            GetPage(name: "/page2", page: ()=> const Page2()),
            GetPage(name: "/page3", page: ()=> const Page3()),
            GetPage(name: "/page4", page: ()=> const Page4()),
      ];,
      title: 'Animated Notch Bottom Bar',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }

5. 动态路由

定于一个动态路由 在路由映射表里面

GetPage(name: '/profile/:userId', page: () => ProfilePage()),

路由跳转

// 跳转到 profile 页面,并传递 userId 参数 
Get.toNamed('/profile/123');

获取路由参数

// 获取动态路由参数 
var userId = Get.parameters['userId'];

6. 路由传参

支持通过 arguments 传递复杂的对象或数据。在跳转时,可以传递参数: 不限于字符串,一个Map,一个List,甚至一个类的实例

Get.to(SecondPage(), arguments: {'id': 123});

在目标页面可以通过 Get.arguments 获取这些参数:

var id = Get.arguments['id'];

也可以通过动态网页链接进行传递,就像web开发一样.

Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");

NextScreen页面 接收

print(Get.parameters['id']);
// out: 354
print(Get.parameters['name']);
// out: Enzo

7. 路由过渡动画

GetX 提供了丰富的页面过渡效果,允许你为每个页面设置不同的过渡动画。例如,可以指定页面从下方滑入:

Get.to(SecondPage(), transition: Transition.downToUp);

常用的过渡类型包括:

  • Transition.fade: 淡入淡出
  • Transition.zoom: 缩放效果
  • Transition.cupertino: 类似 iOS 的过渡效果

你还可以自定义页面过渡动画,满足不同的 UI 需求。

8. 路由中间件

GetX 的路由支持中间件功能,允许在路由跳转之前进行拦截、验证或其他操作。常用于权限控制、重定向等场景。例如,可以创建一个简单的身份验证中间件:

class AuthMiddleware extends GetMiddleware {
  @override
  RouteSettings? redirect(String? route) {
    if (!isLoggedIn) {
      return RouteSettings(name: '/login');
    }
    return null;
  }
}

然后在路由定义中使用中间件:

GetPage(
  name: '/profile',
  page: () => ProfilePage(),
  middlewares: [AuthMiddleware()],
);