Flutter uses Navigator to make local page jumps

Lao Meng's guide: The Navigator component is not used very often, but it works well in some scenarios, such as local form filling out multiple pages, bottom navigation always exists, and each tab navigates its own scenario.

Navigator is a control that manages routes and is normally used directlyNavigator.of(context) method to jump pages, so you can use it directlyNavigator.of(context) Because this control is used in WidgetsApp, the root control of the application is usually MaterialApp, which contains WidgetsApp, so Navigator-related properties can be used directly.

The 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);
  },
)

The initialRoute represents the initialization of the route, and the onGenerateRoute represents the generation of the route based on RouteSettings.

So under what circumstances do you need to use Navigator?Use Navigator where a local page Jump is required, as in the following scenarios:

Headline Client Reporting Scenario

Headline client has a "cross" under each news item. Click to pop up relevant information, click on a part of it, and jump to the report page in the current small window. The effect is as follows:

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

The first page 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 for Navigator is a PageC page, which has the following code:

class PageC extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Card(
        child: Column(
          children: <Widget>[
            _buildItem(Icons.clear, 'Uninterested', 'Reduce this type of content'),
            Divider(),
            _buildItem(Icons.access_alarm, 'Report', 'Title exaggeration, poor content quality, etc.',
                showArrow: true, onPress: () {
              Navigator.of(context).push(MaterialPageRoute(builder: (context) {
                return PageD();
              }));
            }),
            Divider(),
            _buildItem(Icons.perm_identity, 'Author of Lahei: Xinhua Client', ''),
            Divider(),
            _buildItem(Icons.account_circle, 'Shield', 'Military videos, drivers, 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'),
            ],
          ),
        ],
      ),
    );
  }
}

Finally, the local jump effect is achieved, only in the middle area changes, other areas remain unchanged.

Jump inside Tab

Another typical application scenario is to jump within a Tab as follows:

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

The first page 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 page'), icon: Icon(Icons.home)),
          BottomNavigationBarItem(title: Text('book'), icon: Icon(Icons.book)),
          BottomNavigationBarItem(
              title: Text('My'), icon: Icon(Icons.perm_identity)),
        ],
      ),
    );
  }
}

The first page defines three tab s 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 on one of them to jump to the related details page, here for simplicity, only a jump button is put:

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();
            }));
          },
        ),
      ),
    );
  }
}

Detail 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 common, it works well in some scenarios.

Communication

Lao Meng Flutter blog address (nearly 200 control usages): http://laomengit.com

Welcome to the Flutter Exchange Group (WeChat: laomengit), Focus on Public Number (Lao Meng Flutter):

Tags: Mobile

Posted on Tue, 26 May 2020 20:06:31 -0400 by ldsmike88