Flutter页面导航插件navigator的使用

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

Flutter页面导航插件 navigator 的使用

概述

navigator 是一个简单而强大的Flutter导航插件,适用于简单的Flutter应用。它支持深度链接和外部组件的路由,并且不使用“魔法”来实现这些功能。

功能特性

  • 简单易用
  • 使用Flutter的Navigator v1.0
  • 支持深度链接和来自外部组件的路由
  • 不使用“魔法”

开始使用

添加依赖

首先,在你的项目中添加这个包作为依赖:

flutter pub add navigator

然后在你的文件中导入该包:

import 'package:navigator/navigator.dart';

使用方法

设置

  1. 创建一个 List<NavigationPath> 列表:
final navigationPaths = [
  NamedPath(
    pathName: AppLaunchScreen.routeName,
    builder: (_, settings) {
      final redirectionPathName = getValueIfTypeMatched<String>(
        settings.arguments,
      );

      return AppLaunchScreen(
        routePath: redirectionPathName,
        reRoutePath: HomeScreen.route,
      );
    },
  ),
  NamedPath(
    pathName: HomeScreen.routeName,
    builder: (_, __) => const HomeScreen(),
  ),
  NavigationPath(
    matcher: (route) =>
        route?.name?.startsWith('${MovieDetailsScreen.route}/') ?? false,
    builder: (_, settings) {
      return MovieDetailsScreen();
    },
  ),
];
  1. 创建一个包含 NavigationPath 列表的路由配置:
final navigationProvider = RouterConfiguration(navigationPaths);

安装

2.1 在 MaterialApp 中添加路由配置:

child: MaterialApp(
  // ...
  navigatorKey: navigationProvider.navigatorKey,
  onGenerateRoute: navigationProvider.onGenerateRoute,
  onUnknownRoute: navigationProvider.onUnknownRoute,
  // ...    
),

更多设置

使用依赖注入框架(可选)

你可以使用你喜欢的依赖注入框架来提供 List<NavigationPath>RouterConfigurationMaterialApp。以下是一个使用Riverpod的例子:

final navigationProvider = Provider((ref) {
  final paths = ref.read(navigationPaths);

  return RouterConfiguration(paths);
});

final navigationPaths = Provider<List<NavigationPath>>((ref) {
  return [
    NavigationPath(
      matcher: (route) => route?.name == AppLaunchScreen.routeName,
      builder: (_, settings) {
        final pathName = getValueIfTypeMatched<String>(
          settings.arguments,
        );

        return AppLaunchScreen(
          routePath: pathName,
          reRoutePath: HomeScreen.route,
        );
      },
    ),
    NamedPath(
      pathName: UnverifiedAppScreen.routeName,
      builder: (_, __) => const UnverifiedAppScreen(),
    ),
    NavigationPath(
      matcher: (route) =>
          route?.name?.startsWith('${MovieDetailsScreen.route}/') ?? false,
      builder: (_, settings) {
        return MovieDetailsScreen();
      },
    ),
  ];
});

使用时:

final _nav = ref.read(navigationProvider);

// ...
child: MaterialApp(
  // ...
  navigatorKey: _nav.navigatorKey,
  onGenerateRoute: _nav.onGenerateRoute,
  onUnknownRoute: _nav.onUnknownRoute,
  // ...    
),

无上下文导航

你可以使用 RouterConfiguration 实例中的 navigatorState 进行无需上下文的导航:

RouterConfiguration.navigatorState.pushNamed('/some_route');

示例代码

以下是一个完整的示例代码,展示了如何使用 navigator 插件进行页面导航:

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

final navigationPaths = [
  NamedPath(
    pathName: LaunchScreen.routeName,
    builder: (_, settings) {
      final redirectionPathName = getValueIfTypeMatched<String>(
        settings.arguments,
      );

      return LaunchScreen(
        routePath: redirectionPathName,
        reRoutePath: MyHomePage.routeName,
      );
    },
  ),
  NamedPath(
    pathName: MyHomePage.routeName,
    builder: (_, __) => const MyHomePage(title: 'Flutter Demo Home Page'),
  ),
  NavigationPath(
    matcher: (route) =>
        route?.name?.startsWith('${SomeOtherPage.routeName}/') ?? false,
    builder: (_, settings) {
      return const SomeOtherPage();
    },
  ),
];

final navigator = RouterConfiguration(paths: navigationPaths);

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      navigatorKey: navigator.navigatorKey,
      onGenerateRoute: navigator.onGenerateRoute,
      onUnknownRoute: navigator.onUnknownRoute,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  static const String routeName = '/home';

  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: TextButton(
          onPressed: () {
            Navigator.of(context).pushNamed(SomeOtherPage.routeName + '/WORLD');
          },
          child: const Text('GO SOMEWHERE'),
        ),
      ),
    );
  }
}

class LaunchScreen extends StatefulWidget {
  static const String routeName = '/';

  const LaunchScreen({
    Key? key,
    this.routePath,
    required this.reRoutePath,
  }) : super(key: key);

  final String? routePath;
  final String reRoutePath;

  [@override](/user/override)
  State<LaunchScreen> createState() => _LaunchScreenState();
}

class _LaunchScreenState extends State<LaunchScreen> {
  [@override](/user/override)
  void initState() {
    super.initState();
    Future.microtask(_load);
  }

  void _load() async {
    await Future.delayed(const Duration(milliseconds: 1500));
    Navigator.of(context).pushNamedAndRemoveUntil(
      widget.routePath ?? widget.reRoutePath,
      (route) => false,
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: FlutterLogo(size: 150),
      ),
    );
  }
}

class SomeOtherPage extends StatelessWidget {
  static const String routeName = '/some_other';

  const SomeOtherPage({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    final settings = ModalRoute.of(context)?.settings;
    final name = settings?.name;
    final use = name?.replaceFirst('$routeName/', '') ?? 'World';
    return Scaffold(
      appBar: AppBar(
        title: const Text('Some other page'),
      ),
      body: Center(
        child: Text('HELLO $use'),
      ),
    );
  }
}

更多关于Flutter页面导航插件navigator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter页面导航插件navigator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,页面导航是应用开发中非常重要的一部分。Flutter提供了强大的导航功能,主要通过Navigator类来实现。以下是一个关于如何使用Navigator进行页面导航的示例代码,包括基本的页面跳转和返回操作。

1. 创建一个Flutter项目

首先,确保你已经安装了Flutter SDK并设置好了开发环境。然后,使用以下命令创建一个新的Flutter项目:

flutter create my_navigation_app
cd my_navigation_app

2. 创建页面组件

lib目录下,创建两个新的Dart文件,分别用于表示两个不同的页面:first_page.dartsecond_page.dart

first_page.dart

import 'package:flutter/material.dart';

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 使用Navigator.push进行页面跳转
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondPage()),
            );
          },
          child: Text('Go to Second Page'),
        ),
      ),
    );
  }
}

second_page.dart

import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 使用Navigator.pop返回上一页面
            Navigator.pop(context);
          },
          child: Text('Go Back'),
        ),
      ),
    );
  }
}

3. 设置主页面

main.dart文件中,将FirstPage设置为初始页面。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Navigation Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FirstPage(), // 设置FirstPage为初始页面
    );
  }
}

4. 运行应用

使用以下命令运行应用:

flutter run

代码解释

  • FirstPage:这个页面包含一个按钮,点击按钮时会调用Navigator.push方法,将当前页面(FirstPage)推入堆栈,并显示新的页面(SecondPage)。
  • SecondPage:这个页面也包含一个按钮,点击按钮时会调用Navigator.pop方法,从堆栈中弹出当前页面(SecondPage),返回到上一页面(FirstPage)。
  • MaterialApp:这是Flutter应用的根组件,负责配置应用的主题和初始页面。

通过这种方式,你可以在Flutter应用中实现基本的页面导航功能。如果你需要更复杂的导航功能(如带参数的页面跳转、命名路由等),可以进一步学习和使用Flutter的路由库(如flutter_navigation_headersflutter_deeplink)或者Flutter内置的命名路由功能。

回到顶部