Flutter路由管理插件sailor的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter路由管理插件sailor的使用

sailor

anchor_image License: MIT pub_package

一个用于简化导航管理的Flutter插件。

警告:该包仍在开发中,未来可能会有破坏性更改。


索引


设置与使用

1. 创建Sailor实例并添加路由

// Routes类由您创建。
class Routes {
  static final sailor = Sailor();

  static void createRoutes() {
    sailor.addRoute(SailorRoute(
      name: "/secondPage",
      builder: (context, args, params) {
        return SecondPage();
      },
    ));
  }
}

2. 在onGenerateRoute中注册路由,并使用SailornavigatorKey

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sailor Example',
      home: Home(),
      navigatorKey: Routes.sailor.navigatorKey,  // 重要
      onGenerateRoute: Routes.sailor.generator(),  // 重要
    );
  }
}

3. 在应用程序启动前创建路由

void main() async {
  Routes.createRoutes();
  runApp(App());
}

4. 使用Sailor实例进行导航

Routes.sailor.navigate("/secondPage");

提示:

Sailor是一个可调用的类,因此您可以省略navigate方法,直接调用:

Routes.sailor("/secondPage");

传递参数

sailor允许在导航到新页面时传递参数。

1. 在声明路由时声明参数

sailor.addRoutes([
  SailorRoute(
    name: "/secondPage",
    builder: (context, args, params) => SecondPage(),
    params: [
      SailorParam<int>(
        name: 'id',
        defaultValue: 1234,
      ),
    ],
  ),
]);

2. 导航时传递实际参数

Routes.sailor.navigate<bool>("/secondPage", params: {
  'id': 4321,
});

参数获取位置

  • 路由构建器

    sailor.addRoutes([
      SailorRoute(
        name: "/secondPage",
        builder: (context, args, params) {
          // 获取参数
          final id = params.param<int>('id');
          return SecondPage();
        },
        params: [
          SailorParam(
            name: 'id',
            defaultValue: 1234,
          ),
        ],
      ),
    ]);
  • 打开的页面

    class SecondPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final id = Sailor.param<int>(context, 'id');
    
        return Scaffold(
          appBar: AppBar(
            title: Text('Second Page'),
          ),
          body: Center(
            child: Text("Param('id'): $id"),
          ),
        );
      }
    }

确保在声明SailorParam<T>时指定参数类型。此类型用于确保在打开路由时传递正确的参数类型。当前版本中,如果声明的参数类型与传递的参数类型不同,Sailor会记录警告。未来版本可能抛出错误。


传递参数值

sailor允许在导航到新页面时传递参数值。

1. 创建一个扩展自BaseArguments的类

class SecondPageArgs extends BaseArguments {
  final String text;

  SecondPageArgs(this.text);
}

2. 在调用navigate方法时传递这些参数

final response = Routes.sailor.navigate(
  "/secondPage",
  args: SecondPageArgs('Hey there'),
);

3. 在SecondPage中使用Sailor.args获取传递的参数

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final args = Sailor.args<SecondPageArgs>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Compass Example'),
      ),
      body: Center(
        child: Text(args.text),
      ),
    );
  }
}

路由守卫(实验功能)

可以通过route guard保护路由,防止在调用navigate时被打开。

1. 在声明SailorRoute时添加路由守卫

sailor.addRoutes([
  SailorRoute(
    name: "/secondPage",
    builder: (context, args, params) => SecondPage(),
    routeGuards: [
      SailorRouteGuard.simple((context, args, params) async {
        // 验证逻辑
        if (sharedPreferences.getToken() != null) {
          return true;
        }
        return false;
      }),
    ],
  ),
]);

2. 创建路由守卫的方式

  • 使用SailorRouteGuard.simple

    SailorRouteGuard.simple((context, args, params) async {
      // 验证逻辑
      if (sharedPreferences.getToken() != null) {
        return true;
      }
      return false;
    });
  • 扩展SailorRouteGuard类:

    class CustomRouteGuard extends SailorRouteGuard {
      @override
      Future<bool> canOpen(
        BuildContext context,
        BaseArguments args,
        ParamMap paramMap,
      ) async {
        return false;
      }
    }

每个路由守卫的结果为Future<bool>。如果每个路由返回值为true,则路由会被接受并打开;否则路由会被拒绝且不会打开。


页面过渡

sailor内置了页面过渡支持。过渡效果通过SailorTransition指定。

过渡效果优先级

从高到低依次为:

  1. 导航时指定(使用Sailor.navigate)。
  2. 添加路由时指定(SailorRoute)。
  3. 全局过渡(SailorOptions)。

1. 导航时指定过渡效果

Routes.sailor.navigate(
  "/secondPage",
  transitions: [SailorTransition.fade_in],
);

可以同时指定多个过渡效果,这些效果会叠加在一起,顺序可能会影响动画效果。

Routes.sailor.navigate(
  "/secondPage",
  transitions: [
    SailorTransition.fade_in,
    SailorTransition.slide_from_right,
  ],
  transitionDuration: Duration(milliseconds: 500),
  transitionCurve: Curves.bounceOut,
);

可以使用transitionDurationtransitionCurve分别指定持续时间和曲线。

2. 添加路由时指定默认过渡效果

sailor.addRoute(SailorRoute(
  name: "/secondPage",
  defaultTransitions: [
    SailorTransition.slide_from_bottom,
    SailorTransition.zoom_in,
  ],
  defaultTransitionCurve: Curves.decelerate,
  defaultTransitionDuration: Duration(milliseconds: 500),
  builder: (context, args) => SecondPage(),
));

3. 全局过渡

SailorOptions(
  defaultTransitions: [
    SailorTransition.slide_from_bottom,
    SailorTransition.zoom_in,
  ],
  defaultTransitionCurve: Curves.decelerate,
  defaultTransitionDuration: Duration(milliseconds: 500),
)

自定义过渡

虽然sailor提供了许多内置过渡效果,但您仍然可以提供自己的自定义过渡效果。

创建自定义过渡效果
class MyCustomTransition extends CustomSailorTransition {
  @override
  Widget buildTransition(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) {
    return FadeTransition(
      opacity: animation,
      child: child,
    );
  }
}
使用自定义过渡效果
  • 导航时指定:

    Routes.sailor.navigate<bool>(
      "/secondPage",
      customTransition: MyCustomTransition(),
    );
  • 声明路由时指定:

    SailorRoute(
      name: "/secondPage",
      builder: (context, args, params) => SecondPage(),
      customTransition: MyCustomTransition(),
    ),
  • SailorOptions中指定:

    static final sailor = Sailor(
      options: SailorOptions(
        customTransition: MyCustomTransition(),
      ),
    );
自定义过渡优先级

注意:自定义过渡具有最高优先级,如果您提供了自定义过渡,它将覆盖sailor的内置过渡效果。

自定义过渡的效果优先级规则与内置sailor过渡相同,新增规则是:如果两者都提供了过渡效果,则优先使用自定义过渡效果。

例如,在以下代码中,MyCustomTransition将被使用而不是SailorTransition.slide_from_top

Routes.sailor.navigate<bool>(
  "/secondPage",
  transitions: [
    SailorTransition.slide_from_top,
  ],
  customTransition: MyCustomTransition(),
);

同时推送多个路由

sailor允许一次推送多个页面,并获取所有页面的响应结果。

final responses = await Routes.sailor.navigateMultiple(context, [
  RouteArgsPair("/secondPage", SecondPageArgs("Multi Page!")),
  RouteArgsPair("/thirdPage", ThirdPageArgs(10)),
]);

print("Second Page Response ${responses[0]}");
print("Third Page Response ${responses[1]}");

日志导航

使用SailorLoggingObserver来记录应用程序内的push/pop导航。

MaterialAppnavigatorObservers列表中添加SailorLoggingObserver

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Compass Example',
      home: Home(),
      onGenerateRoute: Routes.sailor.generator(),
      navigatorObservers: [
        SailorLoggingObserver(),
      ],
    );
  }
}

一旦添加,开始在您的应用中导航并检查日志。您将看到类似以下内容的日志:

flutter: [Sailor] Route Pushed: (Pushed Route='/', Previous Route='null', New Route Args=null, Previous Route Args=null)
flutter: [Sailor] Route Pushed: (Pushed Route='/secondPage', Previous Route='/', New Route Args=Instance of 'SecondPageArgs', Previous Route Args=null)
flutter: [Sailor] Route Popped: (New Route='/', Popped Route='/secondPage', New Route Args=null, Previous Route Args=Instance of 'SecondPageArgs')

更多关于Flutter路由管理插件sailor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter路由管理插件sailor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


Sailor 是一个用于 Flutter 的路由管理插件,它提供了一种简单而强大的方式来管理应用中的页面导航。通过 Sailor,你可以轻松地定义路由、传递参数、处理返回结果等。以下是如何使用 Sailor 的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 sailor 依赖:

dependencies:
  flutter:
    sdk: flutter
  sailor: ^2.0.0

然后运行 flutter pub get 来获取依赖。

2. 初始化 Sailor

在你的 main.dart 文件中初始化 Sailor

import 'package:flutter/material.dart';
import 'package:sailor/sailor.dart';

void main() {
  SailorOptions sailorOptions = SailorOptions();
  Sailor sailor = Sailor(
    options: sailorOptions,
  );

  sailor.addRoutes([
    SailorRoute(
      name: '/home',
      builder: (context, args, params) => HomePage(),
    ),
    SailorRoute(
      name: '/details',
      builder: (context, args, params) => DetailsPage(),
    ),
  ]);

  runApp(MyApp(sailor: sailor));
}

class MyApp extends StatelessWidget {
  final Sailor sailor;

  MyApp({required this.sailor});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sailor Example',
      navigatorKey: sailor.navigatorKey,
      onGenerateRoute: sailor.generator(),
      home: HomePage(),
    );
  }
}

3. 定义路由

在上面的代码中,我们定义了两个路由:/home/details。每个路由都关联了一个页面。

4. 导航到页面

你可以使用 Sailor 提供的导航方法来跳转到不同的页面。例如:

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Sailor.toNamed('/details');
          },
          child: Text('Go to Details'),
        ),
      ),
    );
  }
}

5. 传递参数

你可以通过 params 参数传递数据到目标页面:

Sailor.toNamed('/details', params: {
  'id': 123,
  'name': 'John Doe',
});

在目标页面中,你可以通过 params 获取这些参数:

class DetailsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final Map<String, dynamic>? params = Sailor.param(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Details Page'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('ID: ${params?['id']}'),
            Text('Name: ${params?['name']}'),
          ],
        ),
      ),
    );
  }
}

6. 处理返回结果

你可以使用 Sailor 来处理页面返回的结果:

Sailor.toNamed('/details').then((result) {
  print('Result from details page: $result');
});

在目标页面中,你可以通过 Navigator.pop 返回结果:

Navigator.pop(context, 'Some result');
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!