flutter之从零开始搭建(二)之 Navigator路由

简介: flutter之从零开始搭建(二)之 Navigator路由

今天我们来讲讲利用Navigator来跳转页面的功能,承接上一篇flutter之从零开始搭建(一)之 BottomNavigationBar继续讲。


页面跳转是我们在入门学习的必备知识,在flutter中,路由跳转是由Navigator来操作的。


Navigator的跳转有两种,一种是显示跳转,需要我们在MaterialPageRoute中指定widget


Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
      //指定跳转的页面
      return new Demo1();
    },));
复制代码


另一种是隐身跳转,这种跳转需要先定义,后使用,跳转方式就像Arouter一样的路径方式,定义部分需要在MaterialApp下定义routes,routes就跟一个Map<path,Page>集合一样,定义好了path对应的page,那么下次跳转,我们就可以针对path去跳转了


@override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"))),
      ),
      //定义路由
      routes: <String,WidgetBuilder>{
        "/demo1":(BuildContext context)=>new Demo1(),
      },
    );
复制代码


跳转使用


Navigator.of(context).pushNamed("/demo1");
复制代码


知道路由如何跳转了,那么,我们开始实战吧


实战


我们看到,路由的跳转都带着一个context参数,这其中有无数的坑需要自己去理解,接下来我会展示出来。


还是承接上一篇博文flutter之从零开始搭建(一)之 BottomNavigationBar,我们先看下MyPage页面,先给出如下代码


import 'package:flutter/material.dart';
import 'package:codelang/widget/Demo1.dart';
class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: new PageWidget(),
      routes: <String,WidgetBuilder>{
        "/demo1":(BuildContext context)=>new Demo1(),
      },
    );
  }
}
class PageWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new PageState();
  }
}
class PageState extends State<PageWidget> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
       body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"),),),
    );
  }
  _pushPage(){
   // Navigator.of(context).pushNamed("/demo1");
    Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
      return new Demo1();
    },));
  }
}
复制代码


大家整体看一下代码,其实没什么错误的地方,看起来一切都很正常,然后我们来看下效果图


image.png


what fuck!!! 跳转的页面怎么没有覆盖全屏,所以,这种方式肯定是不可取的。


我们先停下来想想,我们当前页面PageState是在PageWidget布局上面,

PageWidget还有一个上层布局叫MyPage,我们是不是可以理解为,Navigator.of(context)的这个context指向的是上层MyPage布局的context,导致了页面路由跳转是在MyPage页面进行。


那么有什么解决办法呢?既然是context原因,那么,我们必须得拿到MyPage的上一层context,我们再想想,MyPage相当于一个fragment,是由MainPage页面组成的,我们只需要拿将MainPage页面的context传递给MyPage不就行了吗?接下来开干试试。


打开MainPage


给MyPage的构造方法传递MainPage的context


_bodys = [
      new HomePage(),
      new ShopPage(),
      new MsgPage(),
      new MyPage(context)
    ];
复制代码

打开MyPage


MyPage拿到MainPage的parentContext,然后将parentContext传递给PageWidgetPageState可以通过widget.X的形式,可以拿到PageWidget的变量


import 'package:flutter/material.dart';
import 'package:codelang/widget/Demo1.dart';
class MyPage extends StatelessWidget {
  var parentContext;
  MyPage(this.parentContext);
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: new PageWidget(parentContext),
      routes: <String,WidgetBuilder>{
        "/demo1":(BuildContext context)=>new Demo1(),
      },
    );
  }
}
class PageWidget extends StatefulWidget {
  var parentContext;
  PageWidget(this.parentContext);
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new PageState();
  }
}
class PageState extends State<PageWidget> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
       body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"),),),
    );
  }
  _pushPage(){
//    Navigator.of(widget.parentContext).pushNamed("/demo1");
    Navigator.of(widget.parentContext).push(new MaterialPageRoute(builder: (context) {
      return new Demo1();
    },));
  }
}
复制代码


看下效果图


image.png


嗯,很完美的解决,大家有没有看到我_pushPage方法中注释了的pushNamed方式的跳转,大家猜猜,用这种方式会不会出错?5秒钟的思考哦.


  • 倒计时5s
  • 倒计时4s
  • 倒计时3s
  • 倒计时2s
  • 倒计时1s


OK,来揭晓答案,肯定是不行的,我们知道,routes的定义是在MyPage中的,而我们饿路由跳转拿到的parentContextMainPage的,所以,会报找不到这个路由的错误,如何解决呢?我相信到这大家应该都清楚了,那就是在MainPage中去定义这个routes,具体可以看如下


class MainPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        debugShowCheckedModeBanner: false,
        routes: <String, WidgetBuilder>{
          "/demo1": (BuildContext context) => new Demo1(),
        },
        home: new MainPageWidget());
  }
}
复制代码


这样跳转就可以了,效果图我就不贴出来了,跟上面一样。


你以为就这样结束了?哈哈,早着呢,在写这篇博文的时候,我又发现了一个好玩的地方,为了区分,我在HomePage页面去写这个例子,代码不多,大家看看


HomePage

import 'package:flutter/material.dart';
import 'package:codelang/widget/Demo1.dart';
class HomePage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new HomeState();
  }
}
class HomeState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      home: new Scaffold(
        body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"))),
      ),
    );
  }
  _pushPage() {
//    Navigator.of(context).pushNamed("/demo1");
    Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
      return new Demo1();
    },));
  }
}
复制代码


在这个路由跳转中,我用了context来跳转,大家再猜猜,这种方式可以嘛?5秒钟的思考时间


  • 倒计时5s
  • 倒计时4s
  • 倒计时3s
  • 倒计时2s
  • 倒计时1s


答案揭晓,是可以的哦,为什么这样又可以了呢?


HomePageMyPage的区别在于定义这个widget时,MyPage最外套的一层是StatelessWidget,而HomePage最外套的一层是StatefulWidgetStatelessWidget是一个无状态的widget,难道是他阻隔了context的传递?具体的我也不清楚,只能去猜。


大家再猜猜还是那段注释了的pushNamed的代码,可不可以跳转呢?哈哈,当然是可以的,因为我们在前面的时候,就已经在mainPage中定义了routes


好了,路由这篇说完了,唯一坑就是context的问题,看了这一篇,相信很多人都理解了Navigator如何跳转,下一篇再见吧


目录
相关文章
|
Dart Android开发 UED
带你读《深入浅出Dart》二十七、Flutter路由管理
带你读《深入浅出Dart》二十七、Flutter路由管理
132 0
Flutter Getx 路由 until 方法帮助你跳转指定路由
不少同学都会问我,这样一个场景,当我点击商品列表,进入商品页,点击购买,支付成功后,想返回商品页,或者我的中心的订单列表。怎么做,这中间跨度了 n 个路由。 我不只一次的推荐 GetX 的 until 方法,和 offNamedUntil 方法。 我写了个 demo 今天我们就一起来看下这两个方法如何使用。
1579 0
Flutter Getx 路由 until 方法帮助你跳转指定路由
|
21天前
|
Go 网络架构 开发者
Flutter &鸿蒙next中的路由使用详解【基础使用】
本文介绍了 Flutter 路由系统的使用方法,包括基本路由、命名路由、参数传递、返回参数和动态路由。通过 `Navigator` 类实现页面跳转,支持简单和复杂参数的传递,并可通过 `onGenerateRoute` 实现更灵活的动态路由管理。示例代码展示了如何在实际项目中应用这些技术,帮助开发者构建清晰、易于维护的导航结构。
66 1
|
1月前
|
UED 开发者
flutter:获取对象&路由管理 (四)
本文介绍了Flutter中如何通过Context获取状态对象、使用GlobalKey获取状态对象、基本的路由管理、路由传值、命名路由、返回根路由以及点击图标跳转的方法。示例代码展示了如何在应用中实现这些功能,包括页面跳转、传递参数和返回上一页等操作。
|
6月前
|
安全 Go 数据安全/隐私保护
Flutter开发笔记:Flutter路由技术
Flutter开发笔记:Flutter路由技术
795 0
|
4月前
|
Android开发
Flutter路由跳转参数处理小技巧
Flutter路由跳转参数处理小技巧
42 0
|
6月前
|
前端开发 开发者 iOS开发
【Flutter前端技术开发专栏】Flutter中的路由管理与页面跳转
【4月更文挑战第30天】本文介绍了Flutter的路由管理与页面跳转,包括基本和命名路由管理。基本路由使用`Navigator`的`push`和`pop`方法,如`MaterialPageRoute`和`CupertinoPageRoute`。命名路由则通过路由表注册名称进行跳转,如`Navigator.pushNamed`。此外,还展示了如何通过构造函数、`arguments`和`PageRouteBuilder`进行路由传值。掌握这些知识能提升Flutter开发效率。
112 0
【Flutter前端技术开发专栏】Flutter中的路由管理与页面跳转
|
6月前
|
BI
Flutter笔记:路由观察者
Flutter笔记:路由观察者
300 0
|
6月前
|
UED
Flutter之自定义路由切换动画
Flutter之自定义路由切换动画 在Flutter中,我们可以通过Navigator来实现路由管理,包括路由的跳转和返回等。默认情况下,Flutter提供了一些简单的路由切换动画,但是有时候我们需要自定义一些特殊的动画效果来提高用户体验。本文将介绍如何在Flutter中实现自定义的路由切换动画。
217 0
|
6月前
|
API
Flutter状态管理终极方案GetX第一篇——路由
Flutter状态管理终极方案GetX第一篇——路由 GetX是Flutter中一个非常流行的状态管理库,它不仅提供了简单易用的状态管理功能,还可以帮助我们方便地管理路由。在这篇文章中,我们将介绍如何使用GetX来实现路由管理。
354 0