Skip to content

Document routing #1429

Closed
Closed

Description

@FlutterIssues

From @sethladd on January 25, 2016 19:17

Copied from original issue: flutter/website#143

Activity

  1. added this to the Hackathon milestone on Jan 28, 2016
  2. abarth commented on Feb 5, 2016

    @abarth
    Contributor

    I added a bunch of dartdoc for this today, but we probably want some long-form documentation as well.

  3. sethladd commented on Feb 6, 2016

    @sethladd
    Contributor

    great, thanks Adam!

  4. modified the milestones: , Hackathon on Feb 26, 2016
  5. 3 remaining items

  6. sethladd commented on Dec 2, 2016

    @sethladd
    Contributor

    Comments from a current Flutter user:

    "I have not had success finding information about how to include a second "page" in my app. I gather it has something to do with routes or the Navigator, but I don't know how to implement something like a user pushing a button which takes them to a new screen. Any documentation on this would be fantastic!"

  7. modified the milestones: 2: Make Early Adopters happy, on Dec 2, 2016
  8. mikemimik commented on Dec 13, 2016

    @mikemimik
    Contributor

    Has any progress been made on this, either with dartdocs or a long form document?

  9. Hixie commented on Dec 13, 2016

    @Hixie
    Contributor

    Not particularly.

  10. sethladd commented on Dec 13, 2016

    @sethladd
    Contributor

    From an internal user of Flutter: requesting more docs on "Routes; how to use Navigator and how to use MaterialApp's routes property."

  11. abarth commented on Jan 4, 2017

    @abarth
    Contributor

    We got another request for this doc.

  12. HansMuller commented on Jan 10, 2017

    @HansMuller
    Contributor

    Here's a brief introduction to the Navigator and Routes along with some examples. This material will migrate to a more permanent home soon.

    Mobile apps typically reveal their contents via full-screen elements called "screens" or "pages". In Flutter these elements are called Routes and they're managed with a widget called the Navigator. The Navigator manages a stack of Routes and provides methods for managing the stack, like push and pop.

    The MaterialApp widget creates a Navigator you can refer to with Navigator.of(BuildContext). The MaterialApp's home becomes the route at the bottom of the Navigator's stack. It's what you see when the app is launched.

    To push a new route on the stack you can create an instance of MaterialPageRoute with a builder function that creates whatever you want to appear on the screen. For example:

      Navigator.of(context).push(new MaterialPageRoute(
        builder: buildSamplePage,
      ));
    

    The route defines its widget with a builder function instead of a child widget because it will be built and rebuilt in different contexts depending on when it's pushed and popped.

    The route can be popped, revealing the app's home page, with the Navigator's pop method:

      Navigator.of(context).pop();
    

    It usually isn't necessary to provide a widget that pops the Navigator in an app with a Scaffold because the Scaffold automatically adds a 'back' button to its AppBar. Pressing the back button causes Navigator.pop() to be called. On Android, pressing the system back button does the same thing.

    Here's a complete example.

    import 'package:flutter/material.dart';
    
    class NavigatorDemo extends StatelessWidget {
    
      Widget buildSamplePage(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('Sample Page'),
          ),
          body: new Center(
            child: new FlatButton(
              child: new Text('POP'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('Home Page'),
          ),
          body: new Center(
            child: new FlatButton(
              child: new Text('PUSH'),
              onPressed: () {
                Navigator.of(context).push(new MaterialPageRoute(
                  builder: buildSamplePage,
                ));
              },
            ),
          ),
        );
      }
    }
    
    void main() {
      runApp(new MaterialApp(home: new NavigatorDemo()));
    }
    

    Mobile apps often manage a large number of routes and it's often easiest to refer to them by name. The MaterialApp can be created with a Map<String, WidgetBuilder> which maps from a route's name to a builder function that will create it. To show a route by name:

      Navigator.of(context).pushNamed('myRouteName');
    

    Here's a complete example.

    import 'package:flutter/material.dart';
    
    class MyPage extends StatelessWidget {
      MyPage({ Key key, this.title }) : super(key: key);
    
      final String title;
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text(title),
          ),
        );
      }
    }
    
    class NavigatorDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('Home Page'),
          ),
          body: new MaterialList(
            children: <Widget>[
              new ListItem(
                title: new Text('Show A'),
                onTap: () { Navigator.of(context).pushNamed('A'); },
              ),
              new ListItem(
                title: new Text('Show B'),
                onTap: () { Navigator.of(context).pushNamed('B'); },
              ),
              new ListItem(
                title: new Text('Show C'),
                onTap: () { Navigator.of(context).pushNamed('C'); },
              ),
            ],
          ),
        );
      }
    }
    
    void main() {
      runApp(new MaterialApp(
        home: new NavigatorDemo(),
        routes: <String, WidgetBuilder> {
          'A': (BuildContext context) => new MyPage(title: 'A'),
          'B': (BuildContext context) => new MyPage(title: 'B'),
          'C': (BuildContext context) => new MyPage(title: 'C'),
        },
      ));
    }
    

    Routes don't have to obscure the entire screen. PopupRoutes cover the screen with a barrierColor that can be only partially opaque to allow the current screen to show through. Popup routes are "modal" because they block input to the widgets below.

    There are Flutter functions which create and show popup routes like showDialog(), showMenu(), and showBottomSheet(). There are also Flutter widgets which create popup routes, like PopupMenuButton, DropdownButton. These functions and widgets create internal subclasses of PopupRoute and use the Naviagator's push and pop methods to show and dismiss them.

    You can create your own subclass of PopupRoute to control the animated transition employed to show the route, as well as the color and behavior of the route's modal barrier.

    
    import 'package:flutter/material.dart';
    class _MyPopupRoute extends PopupRoute<Null> {
      _MyPopupRoute({ this.child, this.color });
    
      final Widget child;
      final Color color;
    
      @override
      Duration get transitionDuration => const Duration(milliseconds: 500);
    
      @override
      bool get barrierDismissable => true;
    
      @override
      Color get barrierColor => color;
    
      @override
      Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation) {
        return child;
      }
    
      @override
      Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation, Widget child) {
        final Animation<double> parentAnimation = new CurvedAnimation(
          parent: animation,
          curve: Curves.fastOutSlowIn
        );
        return new FadeTransition(
          opacity: parentAnimation,
          child: new RotationTransition(
            turns: new Tween<double>(begin: 0.5, end: 1.0).animate(parentAnimation),
            child: child,
          ),
        );
      }
    }
    
    
    class NavigatorDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final Color color = Theme.of(context).primaryColor;
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('Home Page'),
          ),
          body: new Center(
            child: new FlatButton(
              child: new Text('PUSH'),
              onPressed: () {
                Navigator.of(context).push(new _MyPopupRoute(
                  color: color.withOpacity(0.15), // don't obscure the widgets below
                  child: new Center(child: new Container(
                    width: 164.0,
                    height: 164.0,
                    decoration: new BoxDecoration(
                      backgroundColor: Colors.white,
                      shape: BoxShape.circle,
                      boxShadow: kElevationToShadow[8],
                    ),
                    child: new Icon(
                      Icons.android,
                      size: 128.0,
                      color: color,
                    )
                  )),
                ));
              },
            ),
          ),
        );
      }
    }
    
    void main() {
      runApp(new MaterialApp(home: new NavigatorDemo()));
    }
    
  13. abarth commented on Jan 11, 2017

    @abarth
    Contributor

    Fixenated by @HansMuller

  14. github-actions commented on Sep 5, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  15. locked as resolved and limited conversation to collaborators on Sep 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions