Example 1

import 'package:dart_printf/dart_printf.dart';
import 'package:flutter/material.dart'; class Book {
final String title;
final String author; Book(this.title, this.author);
} List<Book> books = [
Book('Stranger in a Strange Land', 'Robert A. Heinlein'),
Book('Foundation', 'Isaac Asimov'),
Book('Fahrenheit 451', 'Ray Bradbury'),
]; void main() => runApp(MyApp()); class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MyAppState();
} class _MyAppState extends State<MyApp> {
Book _selectedBook; @override
Widget build(BuildContext context) {
return MaterialApp(
home: Navigator(
pages: [
MaterialPage(
child: BooksPage(books: books, onTapped: _handleBookTapped),
),
if (_selectedBook != null) BookDetailsPage(book: _selectedBook)
],
onPopPage: (route, result) {
printf("page result: %o", result);
if (!route.didPop(result)) {
return false;
} // 通过将_selectedBook设置为null来更新页面列表
setState(() {
_selectedBook = null;
}); return true;
},
),
);
} void _handleBookTapped(Book book) {
setState(() {
_selectedBook = book;
});
}
} class BookDetailsPage extends Page {
final Book book; BookDetailsPage({
this.book,
}) : super(key: ValueKey(book)); Route createRoute(BuildContext context) {
return MaterialPageRoute(
settings: this,
builder: (BuildContext context) {
return BookPage(book: book);
},
);
}
} class BooksPage extends StatelessWidget {
final List<Book> books;
final ValueChanged<Book> onTapped; BooksPage({
@required this.books,
@required this.onTapped,
}); @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('books')),
body: ListView(
children: [
for (var book in books)
ListTile(
title: Text(book.title),
subtitle: Text(book.author),
onTap: () => onTapped(book),
)
],
),
);
}
} class BookPage extends StatelessWidget {
final Book book; BookPage({@required this.book}); @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(book.title)),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Column(
children: [
Text(book.author),
RaisedButton(
onPressed: () => Navigator.of(context).pop(book.title),
child: Text('Pop'),
),
],
),
),
),
);
}
}

Example 2

import 'package:dart_printf/dart_printf.dart';
import 'package:flutter/material.dart'; class Book {
final String title;
final String author; Book(this.title, this.author);
} List<Book> books = [
Book('Stranger in a Strange Land', 'Robert A. Heinlein'),
Book('Foundation', 'Isaac Asimov'),
Book('Fahrenheit 451', 'Ray Bradbury'),
];
void main() => runApp(MyApp()); class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MyAppState();
} class _MyAppState extends State<MyApp> {
BookRouterDelegate _routerDelegate = BookRouterDelegate();
BookRouteInformationParser _routeInformationParser =
BookRouteInformationParser(); @override
Widget build(BuildContext context) {
return MaterialApp.router(
routerDelegate: _routerDelegate,
routeInformationParser: _routeInformationParser,
);
}
} class BookRouteInformationParser extends RouteInformationParser<BookRoutePath> { /// 通常在web程序中手动更改url是会收到通知
@override
Future<BookRoutePath> parseRouteInformation(RouteInformation routeInformation) async {
printf('localtion: %s', routeInformation.location);
final uri = Uri.parse(routeInformation.location);
// Handle '/'
if (uri.pathSegments.length == 0) {
return BookRoutePath.home();
} // Handle '/book/:id'
if (uri.pathSegments.length == 2) {
if (uri.pathSegments[0] != 'book') return BookRoutePath.unknown();
var remaining = uri.pathSegments[1];
var id = int.tryParse(remaining);
if (id == null) return BookRoutePath.unknown();
return BookRoutePath.details(id);
} // Handle unknown routes
return BookRoutePath.unknown();
} @override
RouteInformation restoreRouteInformation(BookRoutePath path) {
if (path.isUnknown) {
return RouteInformation(location: '/404');
}
if (path.isHomePage) {
return RouteInformation(location: '/');
}
if (path.isDetailsPage) {
return RouteInformation(location: '/book/${path.id}');
}
return null;
}
} class BookRouterDelegate extends RouterDelegate<BookRoutePath>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<BookRoutePath> {
final GlobalKey<NavigatorState> navigatorKey; Book _selectedBook;
bool show404 = false; BookRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>(); BookRoutePath get currentConfiguration {
if (show404) {
return BookRoutePath.unknown();
}
return _selectedBook == null
? BookRoutePath.home()
: BookRoutePath.details(books.indexOf(_selectedBook));
} @override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
pages: [
MaterialPage(
key: ValueKey('BooksListPage'),
child: BooksPage(books: books, onTapped: _handleBookTapped),
),
if (show404)
MaterialPage(key: ValueKey('UnknownPage'), child: UnknownScreen())
else if (_selectedBook != null)
BookDetailsPage(book: _selectedBook)
],
onPopPage: (route, result) {
printf("[page result] %o", result);
if (!route.didPop(result)) {
return false;
} // 通过将_selectedBook设置为null来更新页面列表
_selectedBook = null;
show404 = false;
notifyListeners(); return true;
},
);
} @override
Future<void> setNewRoutePath(BookRoutePath path) async {
printf('path id: %o', path.id);
if (path.isUnknown) {
_selectedBook = null;
show404 = true;
return;
} if (path.isDetailsPage) {
if (path.id < 0 || path.id > books.length - 1) {
show404 = true;
return;
} _selectedBook = books[path.id];
} else {
_selectedBook = null;
} show404 = false;
} void _handleBookTapped(Book book) {
_selectedBook = book;
notifyListeners();
}
} class BookDetailsPage extends Page {
final Book book; BookDetailsPage({
this.book,
}) : super(key: ValueKey(book)); Route createRoute(BuildContext context) {
return MaterialPageRoute(
settings: this,
builder: (BuildContext context) {
return BookPage(book: book);
},
);
}
} class BookRoutePath {
final int id;
final bool isUnknown; BookRoutePath.home()
: id = null,
isUnknown = false; BookRoutePath.details(this.id) : isUnknown = false; BookRoutePath.unknown()
: id = null,
isUnknown = true; bool get isHomePage => id == null; bool get isDetailsPage => id != null;
} class BooksPage extends StatelessWidget {
final List<Book> books;
final ValueChanged<Book> onTapped; BooksPage({
@required this.books,
@required this.onTapped,
}); @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('books')),
body: ListView(
children: [
for (var book in books)
ListTile(
title: Text(book.title),
subtitle: Text(book.author),
onTap: () => onTapped(book),
)
],
),
);
}
} class BookPage extends StatelessWidget {
final Book book; BookPage({@required this.book}); @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(book.title)),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Column(
children: [
Text(book.author),
RaisedButton(
onPressed: () => Navigator.of(context).pop(book.title),
child: Text('Pop'),
),
],
),
),
),
);
}
} class UnknownScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('404')),
body: Center(
child: Text('404!'),
),
);
}
}

See also:

Flutter Navigator2.0的更多相关文章

  1. Flutter 1.0 正式版: Google 的便携 UI 工具包

    Flutter 1.0 正式版: Google 的便携 UI 工具包 文 / Tim Sneath,Google Dart & Flutter 产品组产品经理 Flutter 是 Google ...

  2. Flutter 1.0 正式版: Google 的便携 UI 工具包

    简评:所以 React-Native 和 Flutter 该怎么选? 在 10 个月前的 MWC 上,谷歌发布了 Flutter 的 Beta 版本,给跨平台应用开发带来了一种全新的选择,昨天谷歌正式 ...

  3. Flutter 1.0 正式版: Google 的跨平台 UI 工具包

    今天我们非常高兴的宣布,Flutter 的 1.0 版本正式发布!Flutter 是 Google 为您打造的 UI 工具包,帮助您通过一套代码同时在 iOS 和 Android 上构建媲美原生体验的 ...

  4. 【老孟Flutter】Flutter 2.0 重磅更新

    老孟导读:昨天期待已久的 Flutter 2.0 终于发布了,Web 端终于提正了,春季期间我发布的一篇文章,其中的一个预测就是 Web 正式发布,已经实现了,还有一个预测是:2021年将是 Flut ...

  5. XD to Flutter 2.0 现已发布!

    Flutter 是 Google 的开源 UI 工具包.利用它,只需一套代码库,就能开发出适合移动设备.桌面设备.嵌入式设备以及 web 等多个平台的精美应用.过去几年,对于想要打造多平台应用的开发者 ...

  6. 写在Flutter 1.0之前

    开始 大概有半年没有写东西了,感觉时间过得飞快,18年也过一小半,趁着谷歌大会再为Flutter这个耀眼的新星,再吹一波! 都beta3了,1.0还会远吗 Flutter团队依然不紧不慢,一步一个脚印 ...

  7. 学习Flutter从0开始

    一. 认识Flutter 1.1. 什么是Flutter 先看看官方的解释: Flutter is Google's UI toolkit for building beautiful, native ...

  8. 颤振错误:当前Flutter SDK版本为2.1.0-dev.0.0.flutter-be6309690f?

    我刚刚升级了我的扑动,升级后我无法在Android Studio上运行任何扑动项目.我收到此错误消息. The current Dart SDK version -dev.0.0.flutter-be ...

  9. 编写第一个Flutter App(翻译)

    博客搬迁至http://blog.wangjiegulu.com RSS订阅:http://blog.wangjiegulu.com/feed.xml 以下代码 Github 地址:https://g ...

随机推荐

  1. 9.5 自定义包和可见性 go mod

    the-way-to-go_ZH_CN/09.5.md at master · Unknwon/the-way-to-go_ZH_CN https://github.com/Unknwon/the-w ...

  2. cookie,session,token傻傻分不清

    什么是认证(Authentication) • 通俗地讲就是验证当前用户的身份,证明"你是你自己"(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时 ...

  3. 自监督图像论文复现 | BYOL(pytorch)| 2020

    继续上一篇的内容,上一篇讲解了Bootstrap Your Onw Latent自监督模型的论文和结构: https://juejin.cn/post/6922347006144970760 现在我们 ...

  4. OIer 生涯绊脚石

    字符串 哈希进制搞质数 \({\color{OrangeRed}{KMP}}\) 数组别开太大,否则 \({\color{Gold}{TLE}}\) 没有必要 \({\color{Cyan}{strl ...

  5. 使用JSONObject解析和生成json

    创建JSON 引用org.json包,推荐通过maven引用 1.直接构建 JSONObject obj = new JSONObject(); obj.put("sex", &q ...

  6. Folly解读(零) Fbstring—— 一个完美替代std::string的库

    string 常见的三种实现方式 eager copy COW SSO Fbstring 介绍 Storage strategies Implementation highlights Benchma ...

  7. python——模块、标准库、第三方模块安装

    模块(module)简介 模块化--指将一个完整的程序分解为一个一个小的模块,通过将模块组合,来搭建出一个完整的程序. 模块化的特点: ① 方便开发 ② 方便维护 ③ 模块可以复用! 在Python中 ...

  8. HTML字体

    字体相关的样式 color 用来设置字体颜色 font-size 字体的大小 和font-size相关的单位 em 相当于当前元素的一个font-size rem 相当于根元素的一个font-size ...

  9. cassandra权威指南读书笔记--Cassandra架构(3)

    分阶段事件驱动架构 SEDASEDA(Staged Event-Driven Architecture)的核心思想是把一个请求处理过程分成几个Stage,不同资源消耗的Stage使用不同数量的线程来处 ...

  10. F - Cheapest Palindrome

    有一个长度为m的字符串,由n种小写字母组成.对应的n种字母在这个字符串加上或者减去都有相应的费用,现在要将这个字符串变成回文串,问最低消费是多少? Keeping track of all the c ...