Flutter导航管理插件pragmatic_navigation的使用

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

Flutter导航管理插件pragmatic_navigation的使用

pragmatic_navigation 是一个工具包,它为 Navigation 2.0 提供了一个额外的抽象层。目前,它仅暴露了一些用于处理堆栈导航的便捷类。如果您认为可以添加其他类型的简化,请随时联系。

堆栈导航

当整个导航可以被看作是一系列屏幕时,堆栈导航非常有用。您可以在这里了解更多关于这个概念的信息。

堆栈

该包提供了一个 NavigationStack 类,它可以保存一组通用项。它将是您的单一数据源,因此需要维护一个单一且全局可访问的实例。

每次将项目推入堆栈时,相关的路由器会推送相应的页面。如果弹出,则路由器将返回一页。如果替换所有项目,路由器将重新创建所有的导航图。

// 导入必要的库
import 'package:flutter/material.dart';
import 'package:pragmatic_navigation/pragmatic_navigation.dart';

// 定义堆栈项
class MyStackItem {
  final String type;

  MyStackItem(this.type);

  static MyStackItem home() => MyStackItem('home');
  static MyStackItem profile() => MyStackItem('profile');
  static MyStackItem notFound() => MyStackItem('not_found');
}

// 创建导航堆栈
final MyNavigationStack<MyStackItem> myNavigationStack = MyNavigationStack<MyStackItem>();
解析器

该包提供了一个 NavigationStackRouterInformationParser 类,能够将URL段转换为堆栈项,并反之亦然。

一个最小的例子可能是:

// 导入必要的库
import 'package:flutter/material.dart';
import 'package:pragmatic_navigation/pragmatic_navigation.dart';

// 自定义解析器
class MyRouterInformationParser extends NavigationStackRouterInformationParser<MyStackItem> {
  [@override](/user/override)
  Future<MyStackItem> itemForPathSegments(List<String> pathSegments) async {
    try {
      final key = pathSegments[0];

      MyStackItem item;
      switch (key) {
        case "home":
          item = MyStackItem.home();
          break;
        case "profile":
          item = MyStackItem.profile();
          break;
        default:
          item = MyStackItem.notFound();
          break;
      }
      return item;
    } catch (e) {
      return null;
    }
  }

  [@override](/user/override)
  List<String> pathSegmentsForItem(MyStackItem item) => [item.type];
}
路由代理

该包提供了一个 NavigationStackRouterDelegate 类,设计用于与您的 NavigationStack 实例一起工作。它观察给定的堆栈并计算要在导航器内渲染的相应页面。

一个最小的例子可能是:

// 导入必要的库
import 'package:flutter/material.dart';
import 'package:pragmatic_navigation/pragmatic_navigation.dart';

// 自定义路由代理
class MyRouterDelegate extends NavigationStackRouterDelegate<MyStackItem> {
  final NavigationStack<MyStackItem> stack;

  MyRouterDelegate({@required this.stack}) : super(stack: stack);

  [@override](/user/override)
  List<Page> pages({BuildContext context}) => stack
      .mapItems((item, index) {
        Page page;
        switch (item.type) {
          case "home":
            page = MaterialPage(
              key: ValueKey("home"),
              child: MyHome(),
            );
            break;
          case "profile":
            page = MaterialPage(
              key: ValueKey("profile"),
              child: MyProfile(),
            );
            break;
          default:
            page = MaterialPage(child: NotFound());
            break;
        }
        return page;
      })
      .toList();
}

将所有组件组合在一起

由于提供的组件是标准的 Flutter 组件,您可以轻松地与常见的 Flutter Router 一起工作。例如,如果您需要顶级路由,您可以编写类似以下的内容:

// 导入必要的库
import 'package:flutter/material.dart';
import 'package:pragmatic_navigation/pragmatic_navigation.dart';

// 主应用
void main() {
  runApp(MaterialApp.router(
    routerDelegate: MyRouterDelegate(stack: myNavigationStack),
    routeInformationParser: MyRouterInformationParser(),
  ));
}

// 定义主页
class MyHome extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(child: Text('Welcome to Home Page!')),
    );
  }
}

// 定义个人资料页
class MyProfile extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Profile')),
      body: Center(child: Text('Welcome to Profile Page!')),
    );
  }
}

// 定义未找到页面
class NotFound extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Not Found')),
      body: Center(child: Text('Page Not Found!')),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用pragmatic_navigation插件进行导航管理的一个简单示例。这个插件提供了一种声明式的方式来管理Flutter应用的导航。

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

dependencies:
  flutter:
    sdk: flutter
  pragmatic_navigation: ^最新版本号  # 请替换为当前最新版本号

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

接下来,我们来看如何使用这个插件。

1. 设置导航图

首先,你需要定义一个导航图,描述应用中的各个页面和它们之间的关系。

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

// 定义页面
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(child: Text('Home Page')),
    );
  }
}

class DetailsPage extends StatelessWidget {
  final String item;

  DetailsPage({required this.item});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Details')),
      body: Center(child: Text('Details of $item')),
    );
  }
}

// 定义导航图
final navigationGraph = NavigationGraph()
  ..addNode(
    NavigationNode(
      id: 'home',
      builder: (context, arguments) => HomePage(),
    ),
  )
  ..addNode(
    NavigationNode(
      id: 'details',
      builder: (context, arguments) => DetailsPage(item: arguments['item'] as String),
    ),
  )
  ..addEdge(Edge(from: 'home', to: 'details'));

2. 使用导航图

在你的应用的主入口(通常是main.dart文件中的MyApp类)中,使用NavigatorProvider来提供导航图,并使用NavigatorDelegate来管理导航。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      navigatorKey: GlobalKey<NavigatorState>(), // 可选,用于控制导航
      navigatorProviders: [
        NavigatorProvider(
          graph: navigationGraph,
          initialNode: 'home',
        ),
      ],
      home: NavigatorDelegateWidget(
        delegate: GraphNavigatorDelegate(graph: navigationGraph),
      ),
    );
  }
}

3. 导航到详情页

在你的HomePage中,你可以添加一个按钮来导航到DetailsPage。由于pragmatic_navigation管理了导航状态,你可以直接使用context.navigate方法。

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Home Page'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => context.navigate(
                'details',
                arguments: {'item': 'Sample Item'},
              ),
              child: Text('Go to Details'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,当用户点击“Go to Details”按钮时,应用会导航到DetailsPage,并传递一个包含item参数的参数映射。

总结

以上是一个简单的使用pragmatic_navigation插件进行Flutter导航管理的示例。这个插件通过声明式的方式简化了导航管理,使得导航图的定义和页面之间的跳转更加清晰和易于管理。你可以根据应用的复杂程度进一步扩展这个示例,添加更多的页面和导航逻辑。

回到顶部