Flutter uses Navigator to jump to pages

Posted May 27, 20204 min read

Guide for Lao Meng:The frequency of using Navigator component is not very high, but it is very applicable in some scenarios, such as partial form multi-page filling, bottom navigation always exists, and each tab has its own navigation scenario.

Navigator is a control to manage routing. Normally, the method of Navigator.of(context) is used to jump to the page. The reason why Navigator.of(context) can be used directly is because this is used in WidgetsApp Controls, the root control of the application is usually MaterialApp, MaterialApp contains WidgetsApp, so you can directly use the related properties of Navigator.

Navigator usage is very simple, as follows:

Navigator(
  initialRoute:'/',
  onGenerateRoute:(RouteSettings settings) {
    WidgetBuilder builder;
    switch(settings.name) {
      case 'home':
        builder =(context) => PageA();
        break;
      case 'user':
        builder =(context) => PageB();
        break;
    }
    return MaterialPageRoute(builder:builder, settings:settings);
  },

)

initialRoute means to initialize the route, onGenerateRoute means to generate the route according to RouteSettings.

So when should Navigator be used? Navigator is used where a partial page jump is needed, as in the following scenario:

Toutiao client report scene

There is a "cross" under each news in the headline client. Click to pop up the relevant information, click part of it, it will jump to the report page in the current small window, the effect is as follows:

This scenario is a typical scenario using Navigator. Click to report, not to switch pages in full screen, but only to switch on the currently popped up page.

The homepage code is as follows:

@override
Widget build(BuildContext context) {
  return Center(
    child:Container(
      height:350,
      width:300,
      child:Navigator(
        initialRoute:'/',
        onGenerateRoute:(RouteSettings settins) {
          WidgetBuilder builder;
          switch(settins.name) {
            case '/':
              builder =(context) => PageC();
              break;
          }
          return MaterialPageRoute(builder:builder);
        },
     ),
   ),
 );
}

The initial route of Navigator is PageC page, PageC page code is as follows:

class PageC extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child:Card(
        child:Column(
          children:<Widget> [
            _buildItem(Icons.clear, 'not interested', 'reduce such content'),
            Divider(),
            _buildItem(Icons.access_alarm, 'Report', 'Exaggerated title, poor content quality etc.',
                showArrow:true, onPress:() {
              Navigator.of(context) .push(MaterialPageRoute(builder:(context) {
                return PageD();
              }));
            }),
            Divider(),
            _buildItem(Icons.perm_identity, 'pull the black Author:Xinhua client', ''),
            Divider(),
            _buildItem(Icons.account_circle, 'shield', 'military video, pilot, etc.'),
         ],
       ),
     ),
   );
  }

  _buildItem(IconData iconData, String title, String content,
      {bool showArrow = false, Function onPress}) {
    return Row(
      children:<Widget> [
        Icon(iconData),
        SizedBox(
          width:20,
       ),
        Expanded(
          child:Column(
            crossAxisAlignment:CrossAxisAlignment.start,
            children:<Widget> [
              Text(
                title,
                style:TextStyle(fontSize:18),
             ),
              Text(
                content,
                style:TextStyle(
                    color:Colors.black.withOpacity(.5), fontSize:14),
             )
           ],
         ),
       ),
        ! showArrow
            ? Container()
            :IconButton(
                icon:Icon(Icons.arrow_forward_ios),
                iconSize:16,
                onPressed:onPress,
             ),
     ],
   );
  }
}

PageC page jumps to PageD page, PageD page code is as follows:

class PageD extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height:200,
      width:250,
      color:Colors.grey.withOpacity(.5),
      child:Column(
        children:<Widget> [
          Row(
            children:<Widget> [
              IconButton(
                icon:Icon(Icons.arrow_back_ios),
                onPressed:() {
                  Navigator.of(context) .pop();
                },
             ),
              Text('return'),
              SizedBox(
                width:30,
             ),
              Text('Report'),
           ],
         ),
       ],
     ),
   );
  }
}

Navigator_2

Eventually, the local jump effect is realized, only changing in the middle area, and other areas unchanged.

Jump within Tab

There is also a typical application to jump within the Tab, the effect is as follows:

Navigator_3

Bottom navigation has always existed, and each tab has its own navigator.

The homepage code is as follows:

class TabMain extends StatefulWidget {
  @override
  State <StatefulWidget> createState() => _TabMainState();
}

class _TabMainState extends State <TabMain> {
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body:IndexedStack(
        index:_currentIndex,
        children:<Widget> [
          TabNavigator(0),
          TabNavigator(1),
          TabNavigator(2),
       ],
     ),
      bottomNavigationBar:BottomNavigationBar(
        onTap:(int index) {
          setState(() {
            _currentIndex = index;
          });
        },
        currentIndex:_currentIndex,
        items:<BottomNavigationBarItem> [
          BottomNavigationBarItem(title:Text('Home'), icon:Icon(Icons.home)),
          BottomNavigationBarItem(title:Text('Book'), icon:Icon(Icons.book)),
          BottomNavigationBarItem(
              title:Text('My'), icon:Icon(Icons.perm_identity)),
       ],
     ),
   );
  }
}

The home page defines 3 tabs and switching effects.

Define TabNavigator:

class TabNavigator extends StatelessWidget {
  TabNavigator(this.index);

  final int index;

  @override
  Widget build(BuildContext context) {
    return Navigator(
      initialRoute:'/',
      onGenerateRoute:(RouteSettings settins) {
        WidgetBuilder builder;
        switch(settins.name) {
          case '/':
            builder =(context) => ListPage(index);
            break;
        }
        return MaterialPageRoute(builder:builder);
      },
   );
  }
}

List page, this page is generally a List page, click one to jump to the relevant details page, here for simplicity, only a jump button is placed:

class ListPage extends StatelessWidget {
  ListPage(this.index);

  final int index;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar:AppBar(),
      body:Center(
        child:RaisedButton(
          child:Text('$index'),
          onPressed:() {
            Navigator.of(context) .push(MaterialPageRoute(builder:(context) {
              return DetailPage();
            }));
          },
       ),
     ),
   );
  }
}

Details page

class DetailPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar:AppBar(),
      body:Center(
        child:Text('DetailPage'),
     ),
   );
  }
}

Although the Navigator control is not particularly commonly used, it is very suitable in some scenarios.

communicate with

Old Meng Flutter blog address(nearly 200 controls usage): http://laomengit.com

Welcome to join the Flutter communication group(WeChat:laomengit), follow the public number [Lao Meng Flutter]:

| | |