一统天下 flutter - 路由和导航: 路由和导航的进阶

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

一统天下 flutter - 路由和导航: 路由和导航的进阶

示例如下:

lib\route\navigator2.dart

/*
 * 路由和导航的进阶
 *
 * 主要请看 route_c.dart 中的说明
 */

import 'package:flutter/material.dart';
import 'package:flutter_demo/helper.dart';
import 'package:flutter_demo/route/route_a.dart';
import 'package:flutter_demo/route/route_b.dart';
import 'package:flutter_demo/route/route_c.dart';
import 'package:flutter_demo/route/route_d.dart';

class Navigator2Demo extends StatelessWidget {
  const Navigator2Demo({super.key});

  @override
  Widget build(BuildContext context) {
    /// 这里的 MaterialApp 是 main.dart 中的 MaterialApp 的子
    return MaterialApp(
      home: null,

      /// 当 home 设置为 null 时,首次加载会自动导航至 initialRoute 指定的路由
      initialRoute: '/',

      /// 当 home 设置为 null 时,可以通过如下方式,在首次加载的时候 push 多个路由
      /// 下面的运行结果为:首次加载时会显示 RouteBDemo,对 RouteBDemo 做 pop 后会显示 RouteADemo
      /*
      onGenerateInitialRoutes: (settings) {
        return [
          MaterialPageRoute(builder: (context){
            return const RouteADemo();
          }),
          MaterialPageRoute(builder: (context){
            return const RouteBDemo();
          }),
        ];
      },
      */

      /// 一个 MaterialApp 中注册的路由表,在这个 MaterialApp 内的所有路由均可使用
      routes:{
        "/":(context) => const MyNavigator2Demo(title: '主页'),
        "/route_a":(context) => const RouteADemo(),
        "/route_b":(context) => const RouteBDemo(),
        "/route_c":(context) => const RouteCDemo(),
        "/route_d":(context) => const RouteDDemo(),
      },
    );
  }
}

class MyNavigator2Demo extends StatefulWidget {
  const MyNavigator2Demo({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyNavigator2DemoState createState() => _MyNavigator2DemoState();
}

class _MyNavigator2DemoState extends State<MyNavigator2Demo> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Wrap(
        spacing: 10,
        children: [
          MyButton(
            onPressed: () {
              Navigator.of(context).pushNamed('/route_a');
            },
            child: const Text('导航到 route a'),
          ),
        ],
      ),
    );
  }
}

lib\route\route_a.dart

import 'package:flutter/material.dart';

import '../helper.dart';

class RouteADemo extends StatelessWidget {
  const RouteADemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('route a'),
      ),
      body: Wrap(
        spacing: 10,
        children: [
          MyButton(
            onPressed: () {
              Navigator.of(context).pushNamed('/route_b');
            },
            child: const Text('导航到 route b'),
          ),
        ],
      ),
    );
  }
}

lib\route\route_b.dart

import 'package:flutter/material.dart';

import '../helper.dart';

class RouteBDemo extends StatelessWidget {
  const RouteBDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('route b'),
      ),
      body: Wrap(
        spacing: 10,
        children: [
          MyButton(
            onPressed: () {
              Navigator.of(context).pushNamed('/route_c');
            },
            child: const Text('导航到 route c'),
          ),
        ],
      ),
    );
  }
}

lib\route\route_c.dart

import 'package:flutter/material.dart';

import '../helper.dart';

class RouteCDemo extends StatelessWidget {
  const RouteCDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('route c'),
      ),
      body: Wrap(
        spacing: 10,
        children: [
          MyButton(
            onPressed: () {
              /// 返回到顶级 MaterialApp 的根路由(即从路由堆栈中做 pop 直到显示根路由为止)
              Navigator.of(context, rootNavigator:true).pop();
            },
            child: const Text('返回到根路由'),
          ),
          MyButton(
            onPressed: () {
              /// pushReplacementNamed - 用指定的路由替换当前栈顶的路由(效果和 popAndPushNamed 差不多)
              Navigator.of(context).pushReplacementNamed('/route_d');
            },
            child: const Text('导航到 route d(pushReplacementNamed)'),
          ),
          MyButton(
            onPressed: () {
              /// popAndPushNamed - 将当前栈顶的路由 pop 掉,然后 push 指定的路由(效果和 pushReplacementNamed 差不多)
              Navigator.of(context).popAndPushNamed('/route_d');
            },
            child: const Text('导航到 route d(popAndPushNamed)'),
          ),
          MyButton(
            onPressed: () {
              /// popUntil - 在路由堆栈中做 pop 直到显示指定的路由
              Navigator.of(context).popUntil(ModalRoute.withName('/'));
            },
            child: const Text('在路由堆栈中做 pop 直到显示指定的路由'),
          ),
          MyButton(
            onPressed: () {
              /// push 到指定的路由,并在其下做 pop 直到指定的路由
              /// 导航至 route_d,然后 route_d 下面的路由做 pop 直到 route_a,也就是说路由栈中 route_d 的下面是 route_a
              Navigator.of(context).pushNamedAndRemoveUntil('/route_d', ModalRoute.withName('/route_a'));
            },
            child: const Text('在路由堆栈中做 pop 直到显示指定的路由,然后 push 指定的路由'),
          ),
        ],
      ),
    );
  }
}

lib\route\route_d.dart

import 'package:flutter/material.dart';

class RouteDDemo extends StatelessWidget {
  const RouteDDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('route d'),
      ),
      body:null,
    );
  }
}

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

posted @ 2023-03-22 11:04  webabcd  阅读(40)  评论(0编辑  收藏  举报