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. Flash 终将谢幕:微软将于年底停止对 Flash 的支持

    近日,微软宣布将于今年 12 月终止对 Adobe Flash Player 的支持,届时,微软旗下所有浏览器都将无法使用 Flash,Adobe 也不会在今年 12 月后发布安全更新.早在 2017 ...

  2. P4826

    总的来说, 这道题只考查了单纯的建图和最大生成树 但这却是蓝题(问号 题意 题意的理解比较麻烦 简单说就是 n 支队伍比赛,i 号队伍和 j 号队伍比赛可获得 i ^ j 的分数,然后其中一支队伍会输 ...

  3. 改造xxl-job的客户端日志文件生成体系

    为什么要改造XXL-JOB原有的日志文件生成体系   xxl-job原本自己的客户端日志文件生成策略是:一个日志记录就生成一个文件,也就是当数据库存在一条日志logId,对应的客户端就会生成一个文件, ...

  4. http、https比较

    HTTP 超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据, 互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准. 设计HTTP的初衷是 ...

  5. 项目action:前台传多个dataWrap给后台

    业务描述:当前台需要向后台传递多个dataWrap时,需要给后台action加上一段方法,才可以获取到额外的dataWrap. @Override public List<String> ...

  6. JS:replace

    JavaScript中replace() 方法如果直接用str.replace("-","!") 只会替换第一个匹配的字符. 而str.replace(/-/g ...

  7. 深信服edr控制中心漏洞——代码执行

    第一处代码执行 文件:tool/php_cli.php第64行

  8. spark SQL (四)数据源 Data Source----Parquet 文件的读取与加载

    spark SQL Parquet 文件的读取与加载 是由许多其他数据处理系统支持的柱状格式.Spark SQL支持阅读和编写自动保留原始数据模式的Parquet文件.在编写Parquet文件时,出于 ...

  9. EIGRP和OSPF__EIGRP

    EIGRP解释 1.Enhanced Interior Gateway Routing Protocol 即增强内部网关路由协议.EIGRP同内部网关路由选择协议(IGRP)一样,是Cisco公司的私 ...

  10. Australia Trip Memory (>~<)

    近日,掠过空中星尘,喜于"水雾","牛马",晨曦中不情愿地睁开双眼,到达 Australia 这个"人间天堂"那天的场景还似黄粱一梦却已经是 ...