《Flutter 从0到1构建大前端应用》读后感—第7章【路由】

本文深入讲解Flutter中的路由机制,包括基本用法、静态与动态路由、参数回传、路由栈管理及自定义路由的实现。通过实例演示如何构建高效、灵活的页面跳转逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Flutter 《从0到1构建大前端应用》-所有知识点架构

一丶 路由简介

1.基本用法
在这里插入图片描述
2.静态路由

配置路由
main.dart

import 'package:flutter/material.dart';
import 'package:flutter_routes/errorpage.dart';
import 'package:flutter_routes/homepage.dart';
import 'package:flutter_routes/navigator_with_result.dart';
import 'package:flutter_routes/page1.dart';
import 'package:flutter_routes/page2.dart';
import 'package:flutter_routes/page3.dart';
import 'package:flutter_routes/page4.dart';
import 'package:flutter_routes/page5.dart';
import 'package:flutter_routes/pageroutebuilderresult.dart';
import 'package:flutter_routes/splash.dart';
import 'package:flutter_routes/testpageroutebuilder.dart';
import 'package:flutter_routes/todo.dart';
import 'package:flutter_routes/welcome.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter路由',
      initialRoute: '/PageRouteBuilder',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routes: {
        '/page1': (context) => Page1(),
        '/page2': (context) => Page2(),
        '/page3': (context) => Page3(),
        '/page4': (context) => Page4(),
        '/page5': (context) => Page5(),
        '/todo': (context) => TodosScreen(),
        '/splash': (context) => Splash(),
        '/welcome': (context) => Welcome(),
        '/homepage': (context) => HomePage(),
        '/PageRouteBuilder': (context) => TestPageRouteBuilder(),
        '/PageRouteBuilderResult': (context) => PageRouteBuilderResult(),
      },
      onUnknownRoute: (RouteSettings setting) {
        String name = setting.name;
        print("未匹配到路由:$name");
        return new MaterialPageRoute(builder: (context) {
          return new ErrorPage();
        });
      },
      // home: Page1(),
//      home: TodosScreen(
//        todos: List.generate(
//          20,
//          (i) => Todo(
//                'Todo $i',
//                'A description of what needs to be done for Todo $i',
//              ),
//        ),
//      ),
//      home: HomeScreen(),
//      home: Splash(),
      home: Page1(),
    );
  }
}

page1.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class Page1 extends StatelessWidget {

  Page1({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('page1'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('跳转到Page2'),
          onPressed: () {
            //            Navigator.of(context).push(
            //              new MaterialPageRoute(
            //                builder: (context) {
            //                  return new Page2();
            //                },
            //              ),
            //            );
            Navigator.pushNamed(context, '/page2');   //静态路由跳转
          },
        ),
      ),
    );
  }
}

3.动态路由

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class Todo {          //bean实体类
  final String title;
  final String description;

  Todo(this.title, this.description);
}

class TodosScreen extends StatelessWidget {
  final List<Todo> todos;     //集合

  TodosScreen({Key key, @required this.todos}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Todos'),
      ),
      body: ListView.builder(     //遍历数据
        itemCount: todos.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(todos[index].title),
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(    //动态路由带值跳转
                  builder: (context) => DetailScreen(todo: todos[index]),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  // Declare a field that holds the Todo
  final Todo todo;

  // In the constructor, require a Todo
  DetailScreen({Key key, @required this.todo}) : super(key: key);   //接收传过来的todo对象

  @override
  Widget build(BuildContext context) {
    // Use the Todo to create our UI
    return Scaffold(
      appBar: AppBar(
        title: Text("${todo.title}"),   //显示传过来的值
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Text('${todo.description}'),
      ),
    );
  }
}

4.参数回传

import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('参数回传'),
      ),
      body: Center(child: SelectionButton()),
    );
  }
}

class SelectionButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      onPressed: () {
        _navigateAndDisplaySelection(context);
      },
      child: Text('课程选择'),
    );
  }

  _navigateAndDisplaySelection(BuildContext context) async {
    //通过await 的方式,给Navigator 的push结果添加了一个result,这个 result 就是回传的结果
    final result = await Navigator.push(      
      context,
      MaterialPageRoute(builder: (context) => SelectionScreen()),   //动态路由
    );

    Scaffold.of(context)
      ..removeCurrentSnackBar()
      ..showSnackBar(SnackBar(content: Text("$result")));   //通过SnackBar 将回传结果显示出来
  }
}

class SelectionScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('请选择一门课程'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: RaisedButton(
                onPressed: (){
                  Navigator.pop(context, 'Android');    //返回上一级并且回传数据
                },
                child: Text('Android'),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: RaisedButton(
                onPressed: (){
                  Navigator.pop(context, 'IOS');        //返回上一级并且回传数据
                },
                child: Text('IOS'),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: RaisedButton(
                onPressed: (){
                  Navigator.pop(context, 'Flutter');      //返回上一级并且回传数据
                },
                child: Text('Flutter'),
              ),
            )
          ],
        ),
      ),
    );
  }
}

二丶 路由栈

1.路由栈详解

在这里插入图片描述
结论:Navigator 里的push 方法把元素添加到堆栈顶部,而pop则删除了顶部的元素

2.pushReplacementNamed 方法

Navigator.of(context).pushReplacementNamed('/page4');

在这里插入图片描述

3.popAndPushNamed 方法

与pushReplacementNamed 方法相似的有 popAndPushNamed 方法,效果是一致的,只是转场动画效果不同

4.pushNamedAndRemoveUntil 方法
用法一:确保删除homepage前所有路由栈的页面

	Navigator.of(context).pushNamedAndRemoveUntil(
	'/homepage',(Route <dynamic> route) => false);

在这里插入图片描述
用法二:直接跳转回page2,同时删除掉page5~page2之间的页面实例,但是page5页面依然存在

	Navigator.of(context).pushNamedAndRemoveUntil('/page5',
	ModalRoute.withName('/page2'));

在这里插入图片描述
5.popUntil 方法
和pushNamedAndRemoveUntil 有点类似,只不过没有push操作,而是直接pop 到指定页面

	Navigator.popUntil(context, ModalRoute.withName('/page2'));

在这里插入图片描述

三丶 自定义路由

在这里插入图片描述
TestPageRouteBuilder.dart

import 'package:flutter/material.dart';
import 'package:flutter_routes/pageroutebuilderresult.dart';

class TestPageRouteBuilder extends StatefulWidget {
  @override
  _TestPageRouteBuilderState createState() => _TestPageRouteBuilderState();
}

class _TestPageRouteBuilderState extends State<TestPageRouteBuilder> {
  _onButtonTapCustom(Widget page) {     //实现跳转页面并带有动画效果
    Navigator.of(context).push(     //路由跳转
      PageRouteBuilder<Null>(       //路由页面建造者
        //页面建造者:(上下文对象,动画对象,次要的动画对象)
        pageBuilder: (BuildContext context, Animation<double> animation,
            Animation<double> secondaryAnimation) {
          return AnimatedBuilder(     //动画建造者
            animation: animation,     //动画对象
            builder: (BuildContext context, Widget child) {
              return Opacity(         //无透明
                opacity: animation.value, //无透明
                child: page,            //页面组件
              );
            },
          );
        },
        transitionDuration: Duration(milliseconds: 6000),    //持续时间6秒
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PageRouteBuilder'),
      ),
      body: Center(
          child: Column(
        children: <Widget>[
          RaisedButton(
            padding: EdgeInsets.all(10.0),
            onPressed: () {
              _onButtonTapCustom(PageRouteBuilderResult());   //点击跳转页面并附带动画效果
            },
            child: Text(
              '调用自定义路由',
              textAlign: TextAlign.center,
              style: TextStyle(fontSize: 13.0),
            ),
          ),
          Hero(
            tag: "hero1",
            child: ClipOval(      //椭圆形
              child: CustomLogo(   //自定义组件
                size: 60.0,       //传入大小为60
              ),
            ),
          ),
          Hero(
              tag: "hero2",
              child: Material(      //材料
                color: Colors.transparent,
                child: Text(
                  "Hero效果",
                  style: TextStyle(fontSize: 14.0, color: Colors.black),
                ),
              ))
        ],
      )),
    );
  }
}

class CustomLogo extends StatelessWidget {
  final double size;

  CustomLogo({this.size = 200.0});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.lightBlueAccent,
      width: size,
      height: size,
      child: Center(
        child: FlutterLogo(
          size: size,
        ),
      ),
    );
  }
}

PageRouteBuilderResult

import 'package:flutter/material.dart';
import 'package:flutter_routes/testpageroutebuilder.dart';

class PageRouteBuilderResult extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(30.0),
        child: Stack(
          children: <Widget>[
            Align(
              alignment: Alignment.center,
              child: Hero(      //Hero动画
                tag: "hero1",
                child: Container(
                  height: 250.0,
                  width: 250.0,
                  child: CustomLogo(),
                ),
              ),
            ),
            OutlineButton(
              onPressed: () => Navigator.of(context).pop(),
              child: Icon(Icons.close),
            )
          ],
        ),
      ),
    );
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王睿丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值