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. Python基础(if语句、运算符)

    if语句的简单用法 每条if 语句的核心都是一个值为True 或False 的表达式 (简称条件测试),python根据条件测试的值来判断是否执行if语句后面的代码块,如果为true,执行:为fals ...

  2. loj10007线段

    题目描述 数轴上有 n 条线段,选取其中 k 条线段使得这 k 条线段两两没有重合部分,问 k 最大为多少. 输入格式 第一行为一个正整数 n: 在接下来的 n 行中,每行有 2 个数 a_i,b_i ...

  3. POJ 3461__KMP算法

    [题目描述] 法国作家乔治·佩雷克(Georges Perec,1936-1982)曾经写过一本书,<敏感字母>(La disparition),全篇没有一个字母'e'.他是乌力波小组(O ...

  4. 项目Js源码整合

    整合一下目前做的项目中JS中用到的相关源码等,留待记录和使用. 一.ajaxgrid源码部分 1.初始化 2.查询 3.删除 4.保存 5.根据id获取值,时间值等 6.详情.跳转链接 : a 标签 ...

  5. scp命令------两服务器之间传输数据

    scp就是secure copy,是用来进行远程文件拷贝的.数据传输使用 ssh,并且和ssh 使用相同的认证方式,提供相同的安全保证 . 与rcp 不同的是,scp 在需要进行验证时会要求你输入密码 ...

  6. 使用cronolog按日期分割日志

    cronologcronolog是一个简单的过滤程序从标准输入读取日志文件条目,每个条目写入到输出文件指定一个文件名模板和当前的日期和时间.当扩大的文件名更改,关闭当前文件,并打开一个新的. cron ...

  7. Linux常用命令详解(第一章)(ls、man、pwd、cd、mkdir、echo、touch、cp、mv、rm、rmdir、)

    本章命令(共11个): 1 2 3 4 5 6 ls man pwd cd mkdir echo touch cp mv rm rmdir 1. " ls " 作用:列出指定目录下 ...

  8. unix环境高级编程第六章笔记

    口令文件 阴影口令 组文件 附属组ID 登录账户记录 系统标识 口令文件<\h2> /etc/passwd文件是UNIX安全的关键文件之一.该文件用于用户登录时校验用户的口令,文件中每行的 ...

  9. Codeforces Round #673 (Div. 2) D. Make Them Equal(数论/构造)

    题目链接:https://codeforces.com/contest/1417/problem/D 题意 给出一个大小为 $n$ 的正整数数组 $a$ ,每次操作如下: 选择 $i,j$ 和 $x$ ...

  10. Educational Codeforces Round 91 (Rated for Div. 2) A. Three Indices

    题目链接:https://codeforces.com/contest/1380/problem/A 题意 给出一个大小为 $n$ 的排列,找出是否有三个元素满足 $p_i < p_j\ and ...