zoukankan      html  css  js  c++  java
  • Flutter Navigator2.0

    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:

  • 相关阅读:
    idea插件-RestfulToolkit
    java 调试技巧
    js foreach 不能中断的现象及理解
    SpringBoot 内嵌Tomcat的默认线程配置
    SpringMVC中从doDispatch如何一步步调用到controller的方法
    干掉hao123的第n+1种方法
    查找——二叉排序树(代码超详细注释)
    为什么单螺旋桨飞机会左偏?
    【转】Python 魔法方法大全
    通俗的讲解Python中的__new__()方法
  • 原文地址:https://www.cnblogs.com/ajanuw/p/13809050.html
Copyright © 2011-2022 走看看