flutter系列之:Navigator的高级用法

简介: 上篇文章我们讲到了flutter中navigator的基本用法,我们可以使用它的push和pop方法来进行Router之间的跳转。在flutter中一个Router就是一个widget,但是在Android中,一个Router就是Activity,在IOS中,一个Router是一个ViewController。Router除了之前讲过的push和pop方法之外,还有一些更加高级的用法,一起来看看吧。

简介

上篇文章我们讲到了flutter中navigator的基本用法,我们可以使用它的push和pop方法来进行Router之间的跳转。

在flutter中一个Router就是一个widget,但是在Android中,一个Router就是Activity,在IOS中,一个Router是一个ViewController。

Router除了之前讲过的push和pop方法之外,还有一些更加高级的用法,一起来看看吧。

named routes

虽然在flutter中navigator将routers以stack的形式进行存储,能做的也只是push和pop操作,但是事实上Router是可以有名字的。

想想也是,如果Router没有名字的话,那么如何顺利进行跳转呢?不可能每次都new一个Router出来吧。

navigator有一个方法叫做Navigator.pushNamed()用来将带名字的Router压入堆栈,我们来看下它的定义:

static Future<T?> pushNamed<T extends Object?>(
    BuildContext context,
    String routeName, {
    Object? arguments,
  }) {
    return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
  }

这个方法需要传入一个context和对应的routeName,同时还可以带一些参数。

那么怎么用这个方法呢?

首先我们需要定义一些Router,比如说在创建MaterialApp的时候可以传入routes参数,来设置named Routers:

MaterialApp(
  title: '这是named Routers',
  initialRoute: '/firstPage',
  routes: {
    '/firstPage': (context) => const FirstPage(),
    '/secondPage': (context) => const SecondPage(),
  },
)

上面的代码中我们分别定了两个routers,分别是firstPage和secondPage,他们分别对应一个自定义的widget。

定义好Router之后,我们就可以向下面这样使用了:

onPressed: () {
  Navigator.pushNamed(context, '/secondPage');
}

如果要返回第一个页面的话,那么可以调用Navigator.pop方法来实现:

onPressed: () {
  Navigator.pop(context);
}

给named route传参数

在上一节我们讲到pushNamed的时候,还介绍了它还可以接收参数arguments。从定义上可以看到arguments的类型是Object对象,也就是说任何对象都可以作为named route的参数。

那么我们先定义一个对象如下:

class TestArguments {
  final String name;
  final String description;
  TestArguments(this.name, this.description);
}

接下来我们需要创建一个能够接受这个参数的Routers。

因为所有的Routers都是Widget,所以我们需要创建一个Widget,并在这个widget内部接收传入的参数。

在flutter中有两种传递参数的方式,你可以使用ModalRoute.of(),也可以使用onGenerateRoute()。

我们先来看下ModalRoute.of的定义:

static ModalRoute<T>? of<T extends Object?>(BuildContext context) {
    final _ModalScopeStatus? widget = context.dependOnInheritedWidgetOfExactType<_ModalScopeStatus>();
    return widget?.route as ModalRoute<T>?;
  }

它接收一个context参数,然后返回一个route对象。

具体的用法如下:

class FirstPage extends StatelessWidget {
  const FirstPage({super.key});
  static const routeName = '/firstPage';
  @override
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments as TestArguments;
    return Scaffold(
      appBar: AppBar(
        title: Text(args.name),
      ),
      body: Center(
        child: Text(args.description),
      ),
    );
  }
}

除了使用ModalRoute之外,还可以在onGenerateRoute()方法中进行参数传递。onGenerateRoute是在Route生成的时候触发的:

MaterialApp(
  onGenerateRoute: (settings) {
    if (settings.name == FirstPage.routeName) {
      final args = settings.arguments as TestArguments;
      return MaterialPageRoute(
        builder: (context) {
          return TestArguments(
            title: args.title,
            message: args.message,
          );
        },
      );
    }
    return null;
  },
)

onGenerateRoute接收一个settings对象,我们需要在settings对象中设置对应的name和arguments属性。所以我们需要这样调用:

Navigator.pushNamed(
      context,
      FirstPage.routeName,
      arguments: TestArguments(
        '测试',
        '这是一个named Route',
      ),
    );

从Screen返回值

有时候我们需要从一个Screen返回到之前的Screen,并且不是简单的返回,我们还希望知道前一个screen返回了什么结果,然后可以根据前一个screen返回的不同结果来进行不同的处理。

这个时候就需要用到Navigator.pop的传参功能了。

比如我们在第一个页面中点击了按钮,跳转到第二个页面:

final result = await Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const SecondScreen()),
    );

这里我们使用到了Navigator.push方法,并且返回了一个result的值。

我们可以使用这个值来进行一些逻辑判断。

那么这个result的值是哪里传递过来的呢?

没错,就是SecondScreen中的Navigator.pop方法:

Navigator.pop(context, 'Yes');

这里的’Yes’就会传递给result供我们进行逻辑判断。

向Screen传值

有时候我们需要在页面跳转的过程中传递一些参数,那么怎么才能实现Screen之间的参数传递呢?

因为在flutter中所有的Routers都是Widget,所以我们可以在跳转到新的页面的时候直接将参数以构造函数的方式传递给Routers Widget。

比如我们有下面的Screen Widget:

class NameScreen extends StatelessWidget {
  const NameScreen({super.key, required this.name});
  final String name;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('NameScreen'),
      ),
      body: 
      ...
      ;
  }
}

想要传值给它,可以在onTap方法中这样写:

onTap: () {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => NameScreen(name: 'what is your name?'),
          ),
        );

总结

以上就是Navigator的更加高级的用法,我们可以通过Navigator来进行数据传递等操作,从而实现更加复杂的页面功能。


相关文章
|
9月前
Flutter笔记:AnimationMean、AnimationMax 和 AnimationMin 三个类的用法
Flutter笔记:AnimationMean、AnimationMax 和 AnimationMin 三个类的用法
76 3
|
1月前
|
Dart 小程序 前端开发
WebSocket 解析与应用(包含web前端、服务端、小程序、dart/flutter中的用法)
WebSocket 解析与应用(包含web前端、服务端、小程序、dart/flutter中的用法)
297 0
|
1月前
|
开发框架 Java 开发者
Flutter特殊用法介绍
Flutter特殊用法介绍 Flutter是一种开源移动应用程序开发框架,具有高效、快速、美观、灵活等特点。本文将介绍Flutter中的一些特殊用法,帮助开发者更好地使用Flutter进行应用程序开发。
|
存储 前端开发
flutter系列之:在flutter中使用导航Navigator
一个APP如果没有页面跳转那么是没有灵魂的,页面跳转的一个常用说法就是Navigator,flutter作为一个最为优秀的前端框架,Navigator肯定是必不可少的,那么在flutter中如何使用Navigator呢? 一起来看看吧。
flutter系列之:在flutter中使用导航Navigator
|
Android开发 iOS开发
flutter 路由管理- Navigator的push和pop
Navigator类是flutter一个路由管理的组件,通过一个栈来管理活动路由集合,通常当前屏幕显示的页面就是栈顶的路由。
1008 0
|
存储 Dart 前端开发
Flutter(三)——一篇文章掌握Dart语言的用法(三)
Flutter(三)——一篇文章掌握Dart语言的用法(三)
241 0
Flutter(三)——一篇文章掌握Dart语言的用法(三)
|
存储 Dart JavaScript
Flutter(三)——一篇文章掌握Dart语言的用法(一)
Flutter(三)——一篇文章掌握Dart语言的用法(一)
340 0
Flutter(三)——一篇文章掌握Dart语言的用法(一)
flutter系列之:flutter中listview的高级用法
一般情况下,我们使用Listview的方式是构建要展示的item,然后将这些item传入ListView的构造函数即可,通常情况下这样做是够用了,但是不排除我们会有一些其他的特殊需求。 今天我们会来讲解一下ListView的一些高级用法。
|
Dart JavaScript 前端开发
Flutter(三)——一篇文章掌握Dart语言的用法(二)
Flutter(三)——一篇文章掌握Dart语言的用法(二)
251 0
|
1月前
|
缓存 监控 前端开发
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
【4月更文挑战第30天】本文探讨了Flutter应用启动优化策略,包括理解启动过程、资源加载优化、减少初始化工作、界面布局简化、异步初始化、预加载关键数据、性能监控分析以及案例和未来优化方向。通过这些方法,可以缩短启动时间,提升用户体验。使用Flutter DevTools等工具可助于识别和解决性能瓶颈,实现持续优化。
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略