30天计划第8天-路由跳转(页面切换)

-
-
2025-11-02 22:30
  • 学习内容

    1. 基本路由:Navigator.push(跳转到新页面)、Navigator.pop(返回上一页)

    2. 带参数路由:跳转时传值(如从列表页传 ID 到详情页)

  • 实践任务

    1. 做两个页面:“首页” 和 “详情页”,首页按钮跳转到详情页

    2. 首页传 “商品名称” 到详情页,详情页显示该名称

一、路由基础概念

1. 什么是路由

在Flutter中,路由(Route)本质上就是页面(Widget),路由管理就是页面之间的跳转管理。Flutter使用栈(Stack)来管理路由,遵循“先进后出”原则”:

  • 新页面入栈(push)

  • 返回上一页时出栈(pop)

2. 路由的两种实现方式

  • 基本路由:直接通过Navigator类的方法跳转,适合简单场景。

  • 命名路由:提前在MaterialApp中注册路由名称,通过名称跳转,适合复杂应用

二、基本路由操作:跳转与返回

1. Navigator核心方法

  • Navigator.push(context, route):跳转到新页面(入栈)

  • Navigator.pop(content):返回上一页(出栈)

2. 实现第一个页面跳转

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '路由实例',
      home: const HomePage(), // chushihua
    );
  }
}


// 首页
class HomePage extends StatelessWidget{
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('首页')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 点击跳转详情页
            Navigator.push(
              context,
              // 创建路由(指定目标页面)
              MaterialPageRoute(
                builder: (context) => const DetailPage(),
              ),
            );
          },
          child: Text('跳转到详情页'),
        ),
      ),
    );
  }
}

// 详情页
class DetailPage extends StatelessWidget{
  const DetailPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('详情页'),
        // 导航栏返回按钮(可选,系统默认会有)
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () {
            Navigator.pop(context); // 返回上一页
          },
        ),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('这是详情页'),
            const SizedBox(height: 20,),
            // 页面内的返回按钮
            ElevatedButton(
              onPressed: () {
                Navigator.pop(context); // 返回上一页
              },
               child: const Text('返回首页'))
          ],
        ),
      ),
    );
  }
}
  • 运行效果

三、带参数的路由跳转

1. 为什么需要传递参数

实际开发中,页面跳转往往需要携带数据:

  • 列表页跳转到详情页,需要传递“商品ID”或“商品名称”
  • 表单页跳转到结果页,需要传递“用户输入内容”

2. 传递参数的实现步骤

(1)在详情页定义参数接收变量

通过构造函数接收从首页传递的参数(如:商品名称)

class DetailPage extends StatelessWidget {
  // 定义接收的参数变量(商品名称)
  final String productName;

  // 构造函数(必传参数,添加 required 关键字)
  const DetailPage({
    super.key,
    required this.productName, // 必须传递的参数
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("详情页")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 显示接收的参数(商品名称)
            Text(
              "当前商品:$productName", // 使用 $ 符号引用变量
              style: const TextStyle(fontSize: 20),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => Navigator.pop(context),
              child: const Text("返回首页"),
            ),
          ],
        ),
      ),
    );
  }
}

(2)在首页跳转时传递参数

在Navigator.push中创建DetailPage实例时,传入参数

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("首页")),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 跳转时传递参数(商品名称)
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => const DetailPage(
                  productName: "2025新款运动鞋", // 传递的参数值
                ),
              ),
            );
          },
          child: const Text("跳转到详情页"),
        ),
      ),
    );
  }
}

3. 传递多个参数

如果需要传递多个参数(如:商品名称、价格、ID),只需要在详情页中添加更多变量

4. 传递复杂参数(对象)

对于复杂数据(如商品信息对象),可以先定义数据模型,再传递对象

// 1. 定义商品模型类
class Product {
  final int id;
  final String name;
  final double price;
  final String description;

  const Product({
    required this.id,
    required this.name,
    required this.price,
    required this.description,
  });
}

// 2. 详情页接收对象参数
class DetailPage extends StatelessWidget {
  final Product product;

  const DetailPage({
    super.key,
    required this.product,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(product.name)),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("ID:${product.id}"),
            Text("名称:${product.name}"),
            Text("价格:¥${product.price}"),
            const SizedBox(height: 10),
            Text("描述:${product.description}"),
          ],
        ),
      ),
    );
  }
}

// 3. 首页传递对象
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    // 创建商品对象
    const product = Product(
      id: 1002,
      name: "智能手表",
      price: 899.0,
      description: "全触控大屏,支持心率监测和运动模式",
    );

    return Scaffold(
      appBar: AppBar(title: const Text("首页")),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => DetailPage(product: product),
              ),
            );
          },
          child: const Text("查看智能手表详情"),
        ),
      ),
    );
  }
}


目录