Flutter导航管理插件simple_navigation的使用

Flutter导航管理插件simple_navigation的使用

simple_navigation 是一个用于简化命名路由导航的插件,旨在解决 Flutter 中的一个已知问题(Issue 11655),即在非当前屏幕构建时,其子屏幕也会被不必要地重新构建。虽然这不是官方解决方案,但它提供了一种更简洁的方式来管理导航。

简化之处

  • 静态导航:为了简化开发过程,导航是静态的。
  • 无需传递上下文:可以直接调用导航方法。
  • 类名为 Nav:比 Navigation 更短。

限制

  • 单实例:由于是静态的,无法创建多个实例。
  • 不支持 showDialog() 返回值:无法获取弹窗的返回值。
  • 不支持 Hero 小部件:无法与 Hero 小部件一起使用。

特性

  • 后退按钮标题:可以通过回调函数自定义后退按钮的标题。

使用步骤

以下是一个完整的示例,展示如何使用 simple_navigation 插件进行导航管理。

完整示例代码

// Copyright 2020 Peter Alvin. All rights reserved.

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

int counter = 0;

// 定义一个简单的页面状态类
class Scrn extends StatefulWidget {
  Scrn(this.name) {
    print("$name called"); // 打印页面名称
  }

  final String name;

  [@override](/user/override)
  _ScrnState createState() => _ScrnState();
}

class _ScrnState extends State<Scrn> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    String xtra = '';
    if (Nav.hasArgs) {
      xtra = ': ARGS=${Nav.args}'; // 如果有参数,显示参数
    }

    print("scrn build: ${widget.name}$xtra"); // 打印构建信息

    return Column(
      children: <Widget>[
        // 后退按钮
        ElevatedButton(
          child: Text(Nav.backButtonCaption), // 自定义后退按钮标题
          onPressed: () {
            Nav.pop(); // 返回上一页
          },
        ),
        // 显示当前导航栈
        Text('${Nav.stack}', style: TextStyle(fontSize: 20)),
        // 页面标题
        Text('${widget.name}', style: TextStyle(fontSize: 30)),
        // 参数显示
        Text('$xtra', style: TextStyle(fontSize: 15)),
        // 推入页面 A
        ElevatedButton(
          child: Text('push a'),
          onPressed: () {
            Nav.push('/a', {'counter': ++counter}); // 带参数推入页面
          },
        ),
        // 推入页面 B
        ElevatedButton(
          child: Text('push b'),
          onPressed: () {
            Nav.push('/b'); // 无参数推入页面
          },
        ),
        // 替换页面 A
        ElevatedButton(
          child: Text('repl a'),
          onPressed: () {
            Nav.repl('/a'); // 替换当前页面为 A
          },
        ),
        // 替换页面 B
        ElevatedButton(
          child: Text('repl b'),
          onPressed: () {
            Nav.repl('/b'); // 替换当前页面为 B
          },
        ),
        // 推入 Deanna 页面
        ElevatedButton(
          child: Text('push deanna'),
          onPressed: () {
            Nav.push('/deanna'); // 推入 Deanna 页面
          },
        ),
      ],
    );
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
  }

  [@override](/user/override)
  void initState() {
    super.initState();
  }
}

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  print("routes");
  Nav.routes = { // 定义路由表
    '/': (context) => Scrn('home'), // 主页
    '/a': (context) => Scrn('a'), // 页面 A
    '/b': (context) => Scrn('b'), // 页面 B
  };
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Nav( // 使用 Nav 小部件作为根布局
          backButtonCaptionCallback: (String route) {
            String s = route.toUpperCase().replaceAll('/', ''); // 自定义后退按钮标题逻辑
            return s.length == 0 ? 'home' : s;
          },
        ),
      ),
    );
  }
}

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

1 回复

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


simple_navigation 是一个用于 Flutter 的轻量级导航管理插件,它简化了页面导航和路由管理的过程。通过 simple_navigation,你可以更轻松地管理应用程序中的页面跳转,而无需直接使用 Flutter 的 Navigator 类。

安装

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

dependencies:
  flutter:
    sdk: flutter
  simple_navigation: ^1.0.0  # 请使用最新版本

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

基本用法

1. 创建路由表

首先,你需要定义一个路由表,将路由名称映射到对应的页面组件。

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

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

class DetailsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Details')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            SimpleNavigation.pop(context);
          },
          child: Text('Go back'),
        ),
      ),
    );
  }
}

final routes = {
  '/': (context) => HomePage(),
  '/details': (context) => DetailsPage(),
};

2. 初始化 SimpleNavigation

在你的 main.dart 文件中,使用 SimpleNavigation 来初始化应用程序。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Simple Navigation Demo',
      navigatorKey: SimpleNavigation.navigatorKey,  // 使用 SimpleNavigation 的 navigatorKey
      onGenerateRoute: SimpleNavigation.onGenerateRoute(routes),  // 使用 SimpleNavigation 的路由生成器
      initialRoute: '/',
    );
  }
}

3. 导航到其他页面

在应用程序中,你可以使用 SimpleNavigation.pushNamed 来导航到其他页面。

SimpleNavigation.pushNamed(context, '/details');

4. 返回上一页

你可以使用 SimpleNavigation.pop 返回到上一页。

SimpleNavigation.pop(context);

高级用法

传递参数

你可以通过 arguments 参数将数据传递给目标页面。

SimpleNavigation.pushNamed(context, '/details', arguments: {'id': 123});

在目标页面中,你可以通过 ModalRoute.of(context)!.settings.arguments 获取传递的参数。

class DetailsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>;
    final id = args['id'];

    return Scaffold(
      appBar: AppBar(title: Text('Details')),
      body: Center(
        child: Text('ID: $id'),
      ),
    );
  }
}

替换当前页面

你可以使用 SimpleNavigation.pushReplacementNamed 来替换当前页面。

SimpleNavigation.pushReplacementNamed(context, '/details');

清除导航栈并跳转到新页面

你可以使用 SimpleNavigation.pushNamedAndRemoveUntil 来清除导航栈并跳转到新页面。

SimpleNavigation.pushNamedAndRemoveUntil(context, '/details', (route) => false);
回到顶部