在 Flutter 开发中,页面跳转(路由导航)是核心基础功能,而多样化的跳转样式能极大提升 App 的用户体验。本文将从「原生基础样式→自定义样式→第三方库样式→特殊交互样式→跨平台适配」5 大维度,全面拆解 Flutter 中所有可用的页面跳转样式,每个样式都附带 完整可运行代码清晰使用场景,新手可直接复制粘贴使用,进阶开发者也能找到个性化定制方案。

本文核心亮点:

  • 覆盖 15+ 跳转样式,含 iOS/Android 原生、自定义动画、模态框、特殊交互等全场景

  • 每个样式均提供「效果描述+完整代码+适用场景」,拒绝碎片化知识

  • 包含 GetX/GoRouter 第三方库实战,适配中大型项目需求

  • 附跨平台(移动端/Web)适配技巧和常见问题解决方案

前置知识:了解 Flutter 基础路由概念(Navigator、PageRoute),本文示例基于 Flutter 3.22.0 版本,兼容主流版本。

一、基础认知:Flutter 路由跳转核心原理

Flutter 页面跳转本质是「路由栈管理」:通过 Navigator 组件管理路由栈,push 操作将新页面入栈,pop 操作将当前页面出栈。

跳转样式的核心是「过渡动画」,由 PageRoute 子类控制:

  • 原生路由:MaterialPageRoute(Material 风格)、CupertinoPageRoute(iOS 风格),内置默认动画

  • 自定义路由:PageRouteBuilder,可完全自定义过渡动画

  • 第三方路由:GetX/GoRouter 等,封装了更丰富的预设样式和路由管理功能

所有示例均基于两个基础页面:HomePage(首页,跳转发起页)和 TargetPage(目标页,跳转接收页),基础代码如下:

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(backgroundColor: Colors.black, title: const Text("Flutter 跳转样式")),
      body: SafeArea(
        child: Container(
          alignment: Alignment.center,
          color: Colors.pinkAccent,
          child: TextButton(
            onPressed: () {
              // 跳转逻辑写在这里
            },
            child: const Text(
              "跳转目标页",
              style: TextStyle(
                color: Colors.white,
                fontSize: 15,
                fontFamily: "MicrosoftYaHei",
                fontWeight: FontWeight.w400,
              ),
            ),
          ),
        ),
      ),
    );
  }
}





import 'package:flutter/material.dart';

/// 目标页
class TargetPage extends StatelessWidget {
  const TargetPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          backgroundColor: Colors.black,
          title: const Text("目标页"),
          leading: IconButton(
            icon: const Icon(Icons.arrow_back),
            onPressed: () => Navigator.pop(context), // 返回上一页
          )),
      body: SafeArea(
          child: Container(
        alignment: Alignment.center,
        color: Colors.blueAccent,
        child: const Text("这是目标页"),
      )),
    );
  }
}

二、原生自带跳转样式(无依赖,开箱即用)

原生路由无需引入任何第三方库,符合各平台设计规范,适合快速开发和简单场景。

2.1 Android 原生样式(MaterialPageRoute)

效果描述:新页面从屏幕右侧滑入,旧页面从左侧滑出;返回时反向执行(新页面左滑出,旧页面右滑入),是 Android 平台默认跳转样式。

适用场景:Android 端常规页面跳转(如首页→列表页、列表页→详情页)。

完整代码(替换 HomePage 中 onPressed 逻辑):

onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => const TargetPage(),
                settings: const RouteSettings(
                  arguments: "我是从首页传过来的参数", // 路由传参
                ),
              ),
            );
          },

参数接收(在 TargetPage 中获取传参):

// 在 TargetPage 的 build 方法中获取
final String? args = ModalRoute.of(context)?.settings.arguments as String?;
// 使用:Text("接收参数:$args")

2.2 iOS 原生样式(CupertinoPageRoute)

效果描述:新页面从屏幕右侧滑入,同时带有轻微的「从下往上偏移」+「透明度渐变」;返回时支持 iOS 原生侧滑手势(左滑屏幕边缘返回),新页面左滑出并渐隐,旧页面渐显。

适用场景:iOS 端常规页面跳转,解决 MaterialPageRoute 在 iOS 上样式违和的问题。

依赖引入(无需额外依赖,Flutter 原生提供):

import 'package:flutter/cupertino.dart';

完整代码

onPressed: () {
  Navigator.push(
    context,
    CupertinoPageRoute(
      builder: (context) => const TargetPage(),
      fullscreenDialog: false, // 设为true时,新页面从底部滑入(类似弹窗)
      maintainState: true, // 是否保留页面状态(默认true)
    ),
  );
}

三、自定义跳转样式(PageRouteBuilder,无限可能)

通过 PageRouteBuilder 可自定义「入场动画、退场动画、时长、曲线」,实现任意想要的效果,是原生方案中灵活性最高的方式。以下是 8 种最常用的自定义样式,覆盖平移、缩放、渐变等核心场景。

3.1 从下往上滑入(底部弹起)

效果描述:新页面从屏幕底部垂直滑入,占满整个屏幕;返回时从顶部滑出消失,带动画缓动效果。

适用场景:登录页、筛选页、底部操作页、表单页(如收货地址编辑)。

完整代码

onPressed: () {
  Navigator.push(
    context,
    PageRouteBuilder(
      transitionDuration: const Duration(milliseconds: 300), // 动画时长(300ms最舒适)
      reverseTransitionDuration: const Duration(milliseconds: 200), // 返回动画时长
      pageBuilder: (context, animation, secondaryAnimation) {
        // 构建目标页
        return const TargetPage();
      },
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        // 平移动画:从底部(Offset(0,1))滑到顶部(Offset(0,0))
        final tween = Tween(
          begin: const Offset(0, 1), // 起始位置(x=0,y=1:屏幕底部)
          end: const Offset(0, 0),   // 结束位置(屏幕顶部)
        ).chain(CurveTween(curve: Curves.ease)); // 动画曲线(缓动,更自然)

        // 应用动画到子组件(child即目标页)
        return SlideTransition(
          position: animation.drive(tween),
          child: child,
        );
      },
    ),
  );
}

3.2 从上往下滑入(顶部落下)

效果描述:新页面从屏幕顶部垂直滑下,覆盖旧页面;返回时向上滑出消失。

适用场景:顶部通知页、下拉式弹窗、临时提示页(如系统通知详情)。

完整代码(仅修改 transitionsBuilder 中的 tween 起始位置):

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  final tween = Tween(
    begin: const Offset(0, -1), // 起始位置(x=0,y=-1:屏幕顶部外)
    end: const Offset(0, 0),
  ).chain(CurveTween(curve: Curves.ease));

  return SlideTransition(position: animation.drive(tween), child: child);
}

3.3 淡入淡出(渐变显示)

效果描述:新页面从完全透明(opacity=0)渐变为不透明(opacity=1),旧页面保持不变;返回时新页面渐隐消失。

适用场景:轻量页面、引导页、广告页、Web 端页面跳转(避免滑入动画违和)。

完整代码

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  // 透明度动画:从0到1
  final tween = Tween(
    begin: 0.0,
    end: 1.0,
  ).chain(CurveTween(curve: Curves.easeInOut));

  return FadeTransition(
    opacity: animation.drive(tween),
    child: child,
  );
}

3.4 从中心放大(缩放效果)

效果描述:新页面从屏幕中心以极小尺寸(scale=0)放大至全屏,同时伴随透明度渐变;返回时从全屏缩小至中心消失,带动画弹性效果。

适用场景:商品详情页、图片预览页、活动弹窗、核心功能入口页面。

完整代码

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  // 缩放动画+透明度动画组合
  final tween = Tween(
    begin: 0.0,
    end: 1.0,
  ).chain(CurveTween(curve: Curves.elasticOut)); // 弹性曲线,放大后轻微回弹

  return ScaleTransition(
    scale: animation.drive(tween),
    child: FadeTransition(
      opacity: animation.drive(tween),
      child: child,
    ),
  );
}

3.5 从左往右滑入(反向原生)

效果描述:新页面从屏幕左侧滑入,旧页面从右侧滑出;返回时反向执行,与 Android 原生样式相反。

适用场景:左侧菜单联动页面(如侧滑菜单→内容页)、步骤式页面(如注册流程)。

完整代码

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  final tween = Tween(
    begin: const Offset(-1, 0), // 起始位置(x=-1,y=0:屏幕左侧外)
    end: const Offset(0, 0),
  ).chain(CurveTween(curve: Curves.ease));

  return SlideTransition(position: animation.drive(tween), child: child);
}

3.6 旋转+缩放+渐变(炫酷组合)

效果描述:新页面从屏幕中心旋转(0→360度)+ 放大(0→1)+ 透明度渐变(0→1),视觉效果炫酷。

适用场景:活动页、广告页、个性化 App 首页→功能页跳转。

完整代码

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  final tween = Tween(
    begin: 0.0,
    end: 1.0,
  ).chain(CurveTween(curve: Curves.easeInOut));

  return RotationTransition(
    turns: animation.drive(tween), // 旋转角度(0到1圈,即360度)
    child: ScaleTransition(
      scale: animation.drive(tween),
      child: FadeTransition(
        opacity: animation.drive(tween),
        child: child,
      ),
    ),
  );
}

3.7 斜向滑入(对角线方向)

效果描述:新页面从屏幕右下角(或左下角)斜向左上(或右上)滑入,覆盖旧页面;返回时反向滑出。

适用场景:个性化 App 页面跳转、游戏类 App 功能页跳转。

完整代码(右下角→中心):

transitionsBuilder: (context, animation, secondaryAnimation, child) {
  final tween = Tween(
    begin: const Offset(1, 1), // 起始位置(x=1,y=1:屏幕右下角外)
    end: const Offset(0, 0),
  ).chain(CurveTween(curve: Curves.ease));

  return SlideTransition(position: animation.drive(tween), child: child);
}

3.8 无动画跳转(静默切换)

效果描述:页面切换无任何动画,瞬间完成跳转和返回。

适用场景:后台管理页面、数据加载页、无需视觉过渡的页面切换(如设置页→隐私政策页)。

完整代码

onPressed: () {
  Navigator.push(
    context,
    PageRouteBuilder(
      transitionDuration: Duration.zero, // 动画时长设为0
      reverseTransitionDuration: Duration.zero,
      pageBuilder: (context, animation, secondaryAnimation) => const TargetPage(),
    ),
  );
}

四、平台专属模态框样式(iOS/Android 特色)

模态框样式本质是「半屏跳转」,区别于全屏页面,适用于轻量操作场景,原生组件已封装好适配逻辑。

4.1 iOS 底部模态框(showCupertinoModalPopup)

效果描述:新页面从屏幕底部滑入,仅占据部分屏幕高度;顶部有半透明遮罩,点击遮罩或下滑页面可关闭,完全符合 iOS 设计规范。

适用场景:iOS 端筛选页、选项选择页(如性别选择)、底部操作菜单(如下拉刷新选项)。

完整代码

import 'package:flutter/cupertino.dart';

onPressed: () {
  showCupertinoModalPopup(
    context: context,
    // 点击遮罩是否关闭(默认true)
    barrierDismissible: true,
    // 模态框内容(自定义高度和布局)
    builder: (context) => Container(
      height: 300, // 自定义高度(建议200-400)
      color: CupertinoColors.white,
      // 适配iOS样式的列表(可选)
      child: CupertinoListSection(
        children: [
          CupertinoListTile(
            title: const Text("选项1"),
            onTap: () {
              // 点击逻辑
              Navigator.pop(context); // 关闭模态框
            },
          ),
          CupertinoListTile(
            title: const Text("选项2"),
            onTap: () => Navigator.pop(context),
          ),
        ],
      ),
    ),
  );
}

4.2 Android 底部模态框(showModalBottomSheet)

效果描述:新页面从屏幕底部滑入,支持滚动(适配软键盘),顶部有圆角,遮罩为半透明黑色,符合 Material Design 规范。

适用场景:Android 端筛选页、操作菜单、表单填写页(如评论发布)。

完整代码

onPressed: () {
  showModalBottomSheet(
    context: context,
    // 支持滚动(适配软键盘,必须设置)
    isScrollControlled: true,
    // 圆角(可选,更美观)
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
    ),
    // 模态框内容
    builder: (context) => Padding(
      padding: EdgeInsets.only(
        bottom: MediaQuery.of(context).viewInsets.bottom, // 适配软键盘高度
      ),
      child: Container(
        height: 350,
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            const Text("Android 底部模态框", style: TextStyle(fontSize: 18)),
            const SizedBox(height: 20),
            TextField(decoration: const InputDecoration(hintText: "输入内容")),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => Navigator.pop(context),
              child: const Text("确认"),
            ),
          ],
        ),
      ),
    ),
  );
}

4.3 Material 全屏对话框(fullscreenDialog)

效果描述:新页面以淡入+轻微缩放效果显示,页面边缘有圆角,顶部导航栏带「关闭」按钮,聚焦用户操作。

适用场景:Android 端登录页、注册页、编辑页(如个人资料编辑)。

完整代码

onPressed: () {
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => const TargetPage(),
      fullscreenDialog: true, // 开启全屏对话框样式
    ),
  );
}

五、特殊交互跳转样式(提升用户体验)

这类样式通过「元素联动」或「手势交互」实现,让页面跳转更连贯、更有趣味性,是中高端 App 的常用设计。

5.1 Hero 动画跳转(元素无缝联动)

效果描述:两个页面中的「同一个元素」(如图片、卡片)从原页面的位置/大小,平滑动画过渡到目标页面的位置/大小;其他区域伴随淡入淡出效果,实现「无缝联动」。

适用场景:列表图片→图片详情页、商品卡片→商品详情页、头像→个人主页。

完整代码

第一步:首页(HomePage)添加 Hero 元素(如图片):

// HomePage 的 body 部分修改
body: SafeArea(
        child: Container(
          alignment: Alignment.center,
          color: Colors.pinkAccent,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // Hero 元素:必须设置唯一 tag
              Hero(
                tag: "imageHero", // 唯一标识,目标页需相同
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(8),
                  child: Image.network(
                    "https://picsum.photos/200/200", // 示例图片
                    width: 100,
                    height: 100,
                    fit: BoxFit.cover,
                  ),
                ),
              ),
              const SizedBox(height: 20),
              TextButton(
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const TargetPage()),
                  );
                },
                child: const Text(
                  "跳转目标页",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 15,
                    fontFamily: "MicrosoftYaHei",
                    fontWeight: FontWeight.w400,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),

第二步:目标页(TargetPage)添加相同 tag 的 Hero 元素:

// TargetPage 的 body 部分修改
body: SafeArea(
          child: Container(
              alignment: Alignment.center,
              color: Colors.blueAccent,
              child: Hero(
                  tag: "imageHero", // 与首页完全一致
                  child: Image.network(
                    "https://picsum.photos/200/200",
                    width: 300,
                    height: 300,
                    fit: BoxFit.cover,
                  )))),

注意事项:Hero 的 tag 必须全局唯一;两个页面的 Hero 元素建议是同类型组件(如均为 Image),避免动画异常。

5.2 侧滑返回(GetX 路由内置侧滑返回)

效果描述:手指在屏幕左侧滑动,触发页面返回,同时新页面左滑出、旧页面右滑入,符合移动端用户操作习惯。

适用场景:内置 Android/iOS 双端侧滑返回支持。

完整代码

第一步:全局替换根组件(GetMaterialApp 替代原生 MaterialApp

修改项目入口 main.dart,将原生的 MaterialApp 替换为 GetMaterialApp侧滑返回自动生效,无需额外配置),完整示例:

import 'package:flutter/material.dart';
import 'package:get/get.dart'; // 导入GetX
import 'home_page.dart'; // 你的首页

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp( // 核心替换:GetMaterialApp
      title: 'Flutter 侧滑返回',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const HomePage(), // 初始页面
      // 可选全局配置(侧滑返回默认开启,以下为自定义参数)
      popGesture: true, // 强制开启侧滑返回(默认true,可省略)
      defaultTransition: Transition.cupertino, // 全局默认iOS样式(双端适配侧滑)
      transitionDuration: const Duration(milliseconds: 300), // 动画时长
    );
  }
}

第二步:使用 GetX 原生路由跳转(侧滑返回自动支持)

// 首页(HomePage)跳转代码
  onPressed: () {
    // 核心:GetX 跳转方法,侧滑返回自动生效
    Get.to(const TargetPage()); // 跳转到目标页
    // 带参跳转(可选,GetX 路由传参更简洁)
    // Get.to(const TargetPage(), arguments: "传递的参数");
  },


// 目标页(TargetPage)返回上一页(可选,侧滑也能返回)
IconButton(
  icon: const Icon(Icons.arrow_back),
  onPressed: () => Get.back(), // GetX 原生返回方法
)

六、第三方路由库样式(中大型项目首选)

原生路由在「复杂路由管理、全局样式统一、路由拦截」等场景下有局限性,第三方库(GetX/GoRouter)封装了更丰富的预设样式和便捷功能,是中大型项目的首选。

6.1 GetX 路由(轻量、无上下文、样式丰富)

GetX 路由无需 BuildContext,支持全局配置默认样式、单独指定页面样式,预设 10+ 跳转样式,同时支持路由传参、拦截、命名路由。

步骤 1:添加依赖(pubspec.yaml):

dependencies:
  get: ^4.6.5 # 最新版本参考pub.dev

步骤 2:全局配置(main.dart)

import 'package:get/get.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: "Flutter 跳转样式",
      initialRoute: "/", // 初始路由
      // 路由表(命名路由,推荐)
      getPages: [
        GetPage(
          name: "/",
          page: () => const HomePage(),
        ),
        GetPage(
          name: "/target",
          page: () => const TargetPage(),
          transition: Transition.cupertino, // 单独指定该页面样式
          transitionDuration: const Duration(milliseconds: 300),
        ),
      ],
      // 全局默认样式(所有未单独指定的页面生效)
      defaultTransition: Transition.material,
      transitionDuration: const Duration(milliseconds: 200),
    );
  }
}

步骤 3:常用跳转样式示例

// 1. 基础跳转(无上下文)
onPressed: () => Get.to(const TargetPage());

// 2. 单独指定样式(从下往上滑入)
onPressed: () => Get.to(
  const TargetPage(),
  transition: Transition.slideUp, // 样式类型
  duration: const Duration(milliseconds: 300), // 时长
  curve: Curves.ease, // 动画曲线
);

// 3. 命名路由跳转(推荐,便于管理)
onPressed: () => Get.toNamed("/target");

// 4. 底部模态框跳转(GetX 封装)
onPressed: () => Get.bottomSheet(
  Container(
    height: 300,
    color: Colors.white,
    child: const Center(child: Text("底部模态框")),
  ),
  backgroundColor: Colors.white,
  shape: const RoundedRectangleBorder(
    borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
  ),
);

// 5. 无动画跳转
onPressed: () => Get.to(const TargetPage(), transition: Transition.noTransition);

GetX 预设样式汇总(Transition 枚举):

  • `Transition.material`:Android 原生侧滑

  • `Transition.cupertino`:iOS 原生侧滑

  • `Transition.fade`:淡入淡出

  • `Transition.size`:从中心缩放

  • `Transition.slideLeft`:从左往右滑入

  • `Transition.slideRight`:从右往左滑入(原生)

  • `Transition.slideUp`:从下往上滑入

  • `Transition.slideDown`:从上往下滑入

  • `Transition.rotate`:旋转显示

  • `Transition.noTransition`:无动画

七、跨平台适配技巧(移动端/Web)

Flutter 跨平台开发时,需根据平台特性适配跳转样式,避免违和感:

7.1 移动端适配(iOS/Android)

通过 Platform.isIOS/Platform.isAndroid 判断平台,自动选择对应样式:

import 'dart:io';

onPressed: () {
  if (Platform.isIOS) {
    // iOS 用 Cupertino 样式
    Navigator.push(context, CupertinoPageRoute(builder: (context) => const TargetPage()));
  } else {
    // Android 用 Material 样式
    Navigator.push(context, MaterialPageRoute(builder: (context) => const TargetPage()));
  }
}

7.2 Web 端适配

Web 端用户习惯「无动画跳转」或「淡入淡出」,避免移动端滑入动画:

// GetX 中 Web 端全局配置
GetMaterialApp(
  defaultTransition: kIsWeb ? Transition.fade : Transition.material,
  // ...其他配置
);

注:kIsWeb 需导入 package:flutter/foundation.dart

八、常见问题解决方案

8.1 跳转动画卡顿

  • 原因:动画时长过长、组合动画过多、目标页初始化耗时久;

  • 解决方案:将动画时长设为 200-300ms;减少不必要的组合动画;目标页初始化逻辑放入 initState 或使用 Future.delayed 延迟执行。

8.2 Hero 动画异常(闪烁、错位)

  • 原因:两个页面的 Hero 元素 tag 不唯一、父组件有padding/margin、元素类型不一致;

  • 解决方案:确保 tag 全局唯一;统一两个页面 Hero 元素的父组件布局;使用同类型组件(如均为 Image)。

8.3 侧滑返回失效

  • iOS 端:确保使用 CupertinoPageRoute,且未禁用手势;

  • Android 端:使用第三方库(如 flutter_swipe_back),检查侧滑触发宽度配置。

九、总结:样式选型建议

根据项目规模和需求,选择合适的跳转样式和实现方案:

  • 小项目/快速开发:使用原生路由(MaterialPageRoute/CupertinoPageRoute),开箱即用;

  • 个性化需求/中小型项目:使用 GetX 路由,预设样式多、配置简单、无上下文依赖;

  • 大型项目/多模块/跨平台:使用 GoRouter 路由,官方推荐、路由管理能力强、适配性好;

  • 特殊交互需求:使用 Hero 动画+自定义 PageRouteBuilder,提升用户体验。

本文覆盖了 Flutter 中所有主流的页面跳转样式,每个样式均提供完整可运行代码,新手可直接复制使用,进阶开发者可基于示例扩展更多个性化样式。如果有其他样式需求或问题,欢迎在评论区留言讨论!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐