Flutter 导航跳转与返回
  nDUQ4LHdRnl1 2023年11月02日 73 0


准备

Flutter 版本:​​2.5.1​

准备了 ​​3​​ 个页面,代码如下

页面一:

Flutter 导航跳转与返回_sed

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

@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
"second": (content) => const SecondPage() // 跳转第 2 个页面的路由
},
home: Scaffold(
appBar: AppBar(
title: const Text("Haocold"),
),
body: const FirstBody(),
),
);
}
}

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

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "second"); // 跳转第 2 个页面
},
child: const Text("下一个页面"));
}
}

页面二:

Flutter 导航跳转与返回_ide_02

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

@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {"third": (content) => const ThirdPage()}, // 跳转第 3 个页面的路由
home: Scaffold(
appBar: AppBar(
title: const Text("第二个页面"),
leading: BackButton(
onPressed: () {
Navigator.pop(context);
},
),
),
body: const SecondBody(),
),
);
}
}

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

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "third"); // 跳转第 3 个页面
},
child: const Text("下一个页面"));
}
}

页面三:

Flutter 导航跳转与返回_ide_03

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

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("第三个页面"),
leading: BackButton(
onPressed: () {
Navigator.pop(context);
},
),
),
body: ThirdBody(scontext: context),
),
);
}
}

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

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pop(context); // 返回上一个页面
},
child: const Text("上一个页面"));
}
}


返回上一个界面,黑屏了?

Flutter 导航跳转与返回_flutter_04


原因是 ​​context​​ 造成的

跟之前那篇文章说的一样,参见 =>

于是,把上级的 ​​context​​​ 传进来
代码改动如下:

......
body: ThirdBody(scontext: context),
),
);
}
}

class ThirdBody extends StatelessWidget {
const ThirdBody({Key? key, required this.scontext}) : super(key: key);

final BuildContext scontext; // 接收传入的 context

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pop(scontext); // 这里使用传入的 context
},
child: const Text("上一个页面"));
}
}

这次就能返回第 2 个页面了。

Flutter 导航跳转与返回_sed_05


侧滑返回,直接到根视图了?

侧滑返回,不应该返回第 2 个界面么?

Flutter 导航跳转与返回_ide_06


还是 ​​context​​ 造成的

跳转第 ​​2​​​ 个页面相关的 ​​context​​ 与

跳转第 ​​3​​​ 个页面相关的 ​​context​

​不是​​同一个!

所以,还是得把上级的 ​​context​​ 传进来

......
body: SecondBody(scontext: context),
),
);
}
}

class SecondBody extends StatelessWidget {
const SecondBody({Key? key, required this.scontext}) : super(key: key);

final BuildContext scontext; // 接收传入的 context

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pushNamed(scontext, "third");
},
child: const Text("下一个页面")); // 这里使用传入的 context
}
}

并且
要把第 ​​​2​​ 个页面的

routes: {"third": (content) => const ThirdPage()},  // 删掉

合并到第 ​​1​​​ 个页面的 ​​routes​

routes: {
"second": (content) => const SecondPage(),
"third": (content) => const ThirdPage(),
}

这样就可以,侧滑返回上一个页面了

Flutter 导航跳转与返回_ide_07


这是一个彩蛋?

返回到根视图可以通过以下代码
​​​Navigator.popUntil(context, ModalRoute.withName('/root'));​​ 来实现

但如果让你侧滑返回到根视图时
这个 ​​​Bug​​​ 是不是恰好能实现这个功能了呢?
哈哈哈哈~
有点意思~


深入了解 BuildContext

官方文档:

[BuildContext] objects are actually [Element] objects. 
The [BuildContext] interface is used to discourage direct manipulation of [Element] objects.

更多参见 => ​​文章​

部分摘抄:

视图树装载过程

StatelessWidget
- 首先它会调用StatelessWidget的 createElement 方法,并根据这个widget生成StatelesseElement对象。
- 将这个StatelesseElement对象挂载到element树上。
- StatelesseElement对象调用widget的build方法,并将element自身作为BuildContext传入。

StatefulWidget
- 首先同样也是调用StatefulWidget的 createElement方法,并根据这个widget生成StatefulElement对象,并保留widget引用。
- 将这个StatefulElement挂载到Element树上。
- 根据widget的 createState 方法创建State。
- StatefulElement对象调用state的build方法,并将element自身作为BuildContext传入。
- 所以我们在build函数中所使用的context,正是当前widget所创建的Element对象。
当我们在 build 函数中使用Navigator.of(context)的时候
这个context实际上是通过 MyApp 这个widget创建出来的Element对象
而of方法向上寻找祖先节点的时候(MyApp的祖先节点)并不存在MaterialApp,也就没有它所提供的Navigator

所以当我们把Scaffold部分拆成另外一个widget的时候
我们在FirstPage的build函数中
获得了FirstPage的BuildContext
然后向上寻找发现了MaterialApp
并找到它提供的Navigator
于是就可以愉快进行页面跳转了


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  b1UHV4WKBb2S   2023年11月13日   40   0   0 ide抗锯齿
  b1UHV4WKBb2S   2023年11月13日   29   0   0 flutterDart
  zSWNgACtCQuP   2023年11月13日   32   0   0 ide
nDUQ4LHdRnl1