Flutter路由管理插件fast_router的使用

Flutter路由管理插件fast_router的使用

fast_router 是一个基于 fluro 改进的路由管理插件,增加了若干便捷方法,并且不需要使用 context。它支持 iOS 左滑手势和 Android 原生路由跳转。

初始化路由

首先,需要在应用中初始化路由:

FastRouter.configureRouters(FastRouter(), [Routers()]);

然后,在 MaterialApp 中配置 navigatorObserversonGenerateRoute

[@override](/user/override)
Widget build(BuildContext context) {
  return MaterialApp(
    navigatorObservers: [FastRouter.observer],
    onGenerateRoute: FastRouter.router.generator,
    home: SelectPage(),
  );
}

新建 Routers 类统一管理路由

创建一个 Routers 类来统一管理所有路由。这里我们定义了两个路由:/article/empty

import 'package:example/EmptyPage.dart';
import 'package:fast_router/fast_router.dart';
import 'package:flutter/widgets.dart';

import 'article.dart';

class Routers extends ModuleRouter {
  static String _article = "/article";
  static String _empty = "/empty";

  // 定义 article 页面的路由
  static void articlePage(bool rootRefresh, bool configState, bool loadData,
      bool isNew, bool isNavigator) {
    if (isNew) {
      var _arguments = ArticleParamsData(rootRefresh, configState, loadData);
      if (isNavigator) {
        Navigator.of(FastRouter.context)
            .pushNamed(_article, arguments: _arguments);
      } else {
        FastRouter.push(_article, arguments: _arguments);
      }
    } else {
      FastRouter.push("$_article?rootRefresh=$rootRefresh"
          "&configState=$configState&loadData=$loadData");
    }
  }

  // 定义 empty 页面的路由
  static void emptyPage() => FastRouter.push(_empty);

  [@override](/user/override)
  void initPath() {
    define(
      _article,
      (context, parameters, arguments) {
        var rootRefresh;
        var configState;
        var loadData;
        if (parameters != null) {
          rootRefresh = parse(parameters["rootRefresh"]?.first);
          configState = parse(parameters["configState"]?.first);
          loadData = parse(parameters["loadData"]?.first);
        } else if (arguments != null && arguments is ArticleParamsData) {
          rootRefresh = arguments.rootRefresh;
          configState = arguments.configState;
          loadData = arguments.loadData;
        }
        return ArticlePage(
          rootRefresh,
          configState: configState,
          loadData: loadData,
        );
      },
      transitionType: TransitionType.fadeIn,
    );

    define(_empty, (context, parameters, arguments) => EmptyPage());
  }

  /// 因为相互依赖这里不能依赖 fast_develop ,正常项目依赖fast_develop这个库就行,
  static bool parse(dynamic value) {
    // LogUtil.printLog(value);
    if (value is int) {
      return value == 1;
    } else if (value is String) {
      return value == "1" || 
             value.toLowerCase() == "true" || 
             value.toLowerCase() == "ok";
    } else if (value is bool) {
      return value;
    } else {
      return false;
    }
  }
}

页面调用

在页面中调用路由的方法如下:

void pushArticle(bool rootRefresh, bool isConfigState, bool isLoadData) {
  Routers.articlePage(rootRefresh, isConfigState, isLoadData);
}

// 在页面中添加一个列表项,点击后跳转到空页面
ListTile(
  title: Text("空页面,不传参数"),
  onTap: () => Routers.emptyPage(),
)

示例代码

以下是完整的示例代码:

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

import 'package:fast_mvvm/fast_mvvm.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';

import 'article.dart';
import 'routers.dart';

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

class UserModel extends BaseModel {
  Future<bool> login(String account, String psd) async {
    await Future.delayed(const Duration(seconds: 3));
    return true;
  }

  Future<DataResponse<ArticleEntity>> getArticleList() async {
    await Future.delayed(const Duration(seconds: 1));

    var entity = ArticleEntity([
      ArticleItem("1", "好的", "内容内容内容内容内容", DateTime.now().toString()),
      ArticleItem("1", "好的", "内容内容内容内容内容", DateTime.now().toString()),
    ]);

    DataResponse<ArticleEntity> dataResponse =
        DataResponse<ArticleEntity>(entity: entity, totalPageNum: 3);
    return dataResponse;
  }
}

class App extends StatefulWidget {
  const App({Key? key}) : super(key: key);

  [@override](/user/override)
  State<App> createState() => _AppState();
}

class _AppState extends State<App> {
  [@override](/user/override)
  void initState() {
    initMVVM<BaseViewModel>(
      [UserModel()],
      controllerBuild: () => EasyRefreshController(),
      resetRefreshState: (c) => (c as EasyRefreshController).resetRefreshState(),
      finishRefresh: (c, {bool success = true, bool noMore = false}) =>
          (c as EasyRefreshController).finishRefresh(success: success, noMore: noMore),
      resetLoadState: (c) => (c as EasyRefreshController).resetLoadState(),
      finishLoad: (c, {bool success = true, bool noMore = false}) =>
          (c as EasyRefreshController).finishLoad(success: success, noMore: noMore),
    );
    FastRouter.configureRouters(FastRouter(), [Routers()]);
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      navigatorObservers: [FastRouter.observer],
      onGenerateRoute: FastRouter.router.generator,
      home: const SelectPage(),
    );
  }
}

class SelectVM extends BaseViewModel {
  ValueNotifier<bool> isLoadData = ValueNotifier(true);
  ValueNotifier<bool> isConfigState = ValueNotifier(false);
}

class SelectPage extends StatelessWidget with BaseView<SelectVM> {
  const SelectPage({Key? key}) : super(key: key);

  [@override](/user/override)
  ViewConfig<SelectVM> initConfig() => ViewConfig.noLoad(vm: SelectVM());

  [@override](/user/override)
  Widget vBuild(
      BuildContext context, SelectVM vm, Widget? child, Widget? state) {
    return Scaffold(
      appBar: AppBar(title: const Text("选择")),
      body: ListView(
        children: <Widget>[
          ListTile(
            title: const Text("是否加载数据,用来测试状态页和重新加载数据"),
            trailing: ValueListenableBuilder<bool>(
              valueListenable: vm.isLoadData,
              builder: (_, value, __) => Switch(
                value: value,
                onChanged: (value) => vm.isLoadData.value = value,
              ),
            ),
          ),
          ListTile(
            title: const Text("是否单独配置状态页,用来测试状态页和重新加载数据"),
            trailing: ValueListenableBuilder<bool>(
              valueListenable: vm.isConfigState,
              builder: (_, value, __) => Switch(
                value: value,
                onChanged: (value) => vm.isConfigState.value = value,
              ),
            ),
          ),
          ListTile(
            title: const Text("根布局刷新"),
            onTap: () => Routers.articlePage(
                true, vm.isConfigState.value, vm.isLoadData.value),
          ),
          ListTile(
            title: const Text("根布局不刷新"),
            onTap: () => Routers.articlePage(
                false, vm.isConfigState.value, vm.isLoadData.value),
          ),
          ListTile(
            title: const Text("新的参数方式"),
            onTap: () => Routers.articlePage(
              true,
              vm.isConfigState.value,
              vm.isLoadData.value,
              isNew: true,
            ),
          ),
          ListTile(
            title: const Text("Navigator的参数方式"),
            onTap: () => Routers.articlePage(
              true,
              vm.isConfigState.value,
              vm.isLoadData.value,
              isNew: true,
              isNavigator: true,
            ),
          ),
          ListTile(
            title: const Text("空页面,不传参数"),
            onTap: () => Routers.emptyPage(),
          ),
        ],
      ),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用fast_router插件进行路由管理的示例代码。fast_router是一个轻量级的Flutter路由管理插件,它简化了路由的定义和导航过程。

首先,确保你已经在pubspec.yaml文件中添加了fast_router依赖:

dependencies:
  flutter:
    sdk: flutter
  fast_router: ^最新版本号  # 请替换为最新的版本号

然后,运行flutter pub get来安装依赖。

接下来,我们来看如何配置和使用fast_router

1. 配置Router

首先,定义一个全局的Router配置类。这个类将包含所有的路由定义。

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

// 定义路由配置类
class MyRouter {
  static final Map<String, WidgetBuilder> routes = {
    '/': (context) => HomeScreen(),
    '/details': (context) => DetailsScreen(),
    // 可以继续添加更多的路由
  };

  // 定义全局的导航器
  static Router getRouter(BuildContext context) {
    return Router(
      routes: routes,
    );
  }
}

2. 初始化Router

在你的应用入口文件(通常是main.dart)中,初始化并使用这个Router。

import 'package:flutter/material.dart';
import 'package:fast_router/fast_router.dart';
import 'my_router.dart';  // 导入你定义的路由配置类

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: MyRouter.getRouter(context),
      routeInformationParser: Router.routeInformationParser,
    );
  }
}

3. 定义屏幕

接下来,定义你的屏幕(例如,HomeScreenDetailsScreen)。

import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 使用Router进行导航
            Router.of(context).navigateTo('/details');
          },
          child: Text('Go to Details'),
        ),
      ),
    );
  }
}

class DetailsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Details Screen'),
      ),
      body: Center(
        child: Text('This is the details screen.'),
      ),
    );
  }
}

4. 运行应用

现在,你可以运行你的Flutter应用。点击HomeScreen上的按钮,应该会导航到DetailsScreen

这个示例展示了如何使用fast_router进行基本的路由管理。fast_router提供了简洁的API来定义和使用路由,使得路由管理变得更加简单和直观。如果你需要更高级的功能,比如参数传递、嵌套路由等,可以查阅fast_router的官方文档获取更多信息。

回到顶部