Android实现页面跳转(附带源码)

【Android开发实战】实现页面跳转(超详细讲解+完整代码+原理解析)

下面开始正文:

一、项目介绍

在 Android 应用中,页面跳转(Navigation) 是最基础也是最关键的功能之一。它承载了用户流转、信息展示、功能隔离等核心逻辑。一个完备的页面跳转方案,不仅要实现“从 A 页面跳转到 B 页面”,还要兼顾以下要点:

传递参数:基本类型、复杂对象、序列化/Parcelable 数据;

返回结果:B 页面操作完成后通知 A 页面;

动画效果:入场/出场动画提升用户体验;

统一管理:集中管理路由、避免硬编码 Intent;

架构兼容:支持 Activity、Fragment、Jetpack Navigation;

安全性:防止未授权跳转、保护隐私参数;

可测试:易于单元测试和 UI 自动化测试。

本篇教程将从基础原理到高级扩展,全方位剖析 Android 页面跳转机制,演示多种实现方式(Intent、startActivityForResult、Jetpack Navigation Component、自定义 Router),并提供统一封装的路由工具类,实现高复用、可测试、可扩展的页面跳转方案。全文超 10000 字,所有 Java/Kotlin 类与 XML 布局整合在一个代码块,通过注释区分,便于复制与集成。

二、相关知识详解

Intent 基础

分类:显式 Intent、隐式 Intent;

组成:Action、Data、Category、Extras、Flags;

参数传递:putExtra()(基本类型、Bundle)、Serializable、Parcelable。

Activity 间跳转

startActivity(Intent)、startActivityForResult(Intent, requestCode);

onActivityResult() 处理返回结果;

Flags:FLAG_ACTIVITY_SINGLE_TOP、FLAG_ACTIVITY_CLEAR_TOP、FLAG_ACTIVITY_NEW_TASK 等。

Fragment 跳转

FragmentManager、FragmentTransaction 的 add()、replace()、addToBackStack();

getParentFragmentManager() vs getChildFragmentManager();

返回栈管理与自定义动画:setCustomAnimations()。

Jetpack Navigation Component

NavHostFragment、NavController、Navigation Graph;

Safe Args 插件生成类型安全跳转方法;

Deep Link 支持。

路由框架

ARouter、ActivityRouter、自定义 Router;

注解 + 反射/APT 方式自动生成跳转表;

动画与过度

overridePendingTransition() 设置 Activity 转场动画;

FragmentTransaction.setTransition() 或 setCustomAnimations()。

安全跳转

跳转前校验权限、登录状态;

参数签名与加密。

三、项目实现思路

分层结构

UI 层(Activity/Fragment)只负责展示与交互;

路由层(Router)负责 Intent 构造与跳转;

结果回调层(Callback)解耦来源与目标页面;

配置层(RouteConfig)集中管理路由路径与参数键名。

核心流程

A 调用 Router.navigateTo(context, RouteConfig.PAGE_B, params);

Router 根据路径构建 Intent/Bundle 并启动;

B 在 onCreate() 中读取参数;

B 调用 Router.finishWithResult(this, resultParams) 返回;

Router 在 A 的 onActivityResult() 中分发回调。

技术实现

使用 注解+APT(AutoService + JavaPoet)生成 RouteRegistry;

Router 调用 RouteRegistry.getIntent(context, path, bundle);

支持 Activity 和 Fragment 两种跳转目标。

// ======================================================

// 文件:app/src/main/java/com/example/router/RouteConfig.java

// 作用:集中管理路由路径与参数键名

// ======================================================

package com.example.router;

public class RouteConfig {

public static final String PAGE_HOME = "/home";

public static final String PAGE_DETAIL = "/detail";

public static final String KEY_ITEM_ID = "item_id";

public static final String KEY_USER_NAME = "user_name";

public static final int REQ_DETAIL = 1001;

}

// ======================================================

// 文件:app/src/main/java/com/example/router/Router.java

// 作用:路由工具类,封装跳转与结果回调

// ======================================================

package com.example.router;

import android.app.Activity;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import androidx.annotation.NonNull;

public class Router {

// 跳转到指定页面

public static void navigateTo(@NonNull Context ctx, @NonNull String path, Bundle params) {

Intent intent = new Intent(ctx, getActivityClass(path));

if (params != null) intent.putExtras(params);

ctx.startActivity(intent);

if (ctx instanceof Activity) {

((Activity) ctx).overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);

}

}

// 带返回结果的跳转

public static void navigateForResult(@NonNull Activity act, @NonNull String path, Bundle params, int requestCode) {

Intent intent = new Intent(act, getActivityClass(path));

if (params != null) intent.putExtras(params);

act.startActivityForResult(intent, requestCode);

act.overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);

}

// 从回调中获取结果

public static Bundle handleResult(int requestCode, int resultCode, Intent data) {

if (data != null && data.getExtras() != null) {

return data.getExtras();

}

return null;

}

// 简单映射路径到 Activity class

private static Class getActivityClass(String path) {

switch (path) {

case RouteConfig.PAGE_HOME: return com.example.ui.HomeActivity.class;

case RouteConfig.PAGE_DETAIL: return com.example.ui.DetailActivity.class;

default: throw new IllegalArgumentException("Unknown path: " + path);

}

}

}

// ======================================================

// 文件:app/src/main/java/com/example/ui/HomeActivity.java

// 作用:首页,演示无参跳转与带参跳转

// ======================================================

package com.example.ui;

import android.content.Intent;

import android.os.Bundle;

import android.widget.Button;

import android.widget.Toast;

import androidx.annotation.Nullable;

import androidx.appcompat.app.AppCompatActivity;

import com.example.router.RouteConfig;

import com.example.router.Router;

public class HomeActivity extends AppCompatActivity {

private Button btnToDetail, btnToDetailForResult;

@Override protected void onCreate(Bundle s) {

super.onCreate(s);

setContentView(R.layout.activity_home);

btnToDetail = findViewById(R.id.btnToDetail);

btnToDetailForResult = findViewById(R.id.btnToDetailForResult);

btnToDetail.setOnClickListener(v -> {

// 无参跳转

Router.navigateTo(this, RouteConfig.PAGE_DETAIL, null);

});

btnToDetailForResult.setOnClickListener(v -> {

// 带参跳转并期待结果

Bundle params = new Bundle();

params.putInt(RouteConfig.KEY_ITEM_ID, 123);

params.putString(RouteConfig.KEY_USER_NAME, "张三");

Router.navigateForResult(this, RouteConfig.PAGE_DETAIL, params, RouteConfig.REQ_DETAIL);

});

}

@Override protected void onActivityResult(int req, int res, Intent data) {

super.onActivityResult(req, res, data);

if (req == RouteConfig.REQ_DETAIL && res == RESULT_OK) {

Bundle result = Router.handleResult(req, res, data);

if (result != null) {

String msg = "Detail 返回: " + result.getString(RouteConfig.KEY_USER_NAME);

Toast.makeText(this, msg, Toast.LENGTH_LONG).show();

}

}

}

}

// ======================================================

// 文件:app/src/main/java/com/example/ui/DetailActivity.java

// 作用:详情页,演示接收参数与返回结果

// ======================================================

package com.example.ui;

import android.content.Intent;

import android.os.Bundle;

import android.widget.Button;

import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.example.router.RouteConfig;

import com.example.router.Router;

public class DetailActivity extends AppCompatActivity {

private TextView tvInfo;

private Button btnFinish;

@Override protected void onCreate(Bundle s) {

super.onCreate(s);

setContentView(R.layout.activity_detail);

tvInfo = findViewById(R.id.tvInfo);

btnFinish = findViewById(R.id.btnFinish);

// 读取传参

Bundle params = getIntent().getExtras();

if (params != null) {

int itemId = params.getInt(RouteConfig.KEY_ITEM_ID, -1);

String name= params.getString(RouteConfig.KEY_USER_NAME, "未提供");

tvInfo.setText("接收到参数:itemId=" + itemId + ",userName=" + name);

}

btnFinish.setOnClickListener(v -> {

// 返回结果

Intent data = new Intent();

Bundle result = new Bundle();

result.putString(RouteConfig.KEY_USER_NAME, "李四-回传");

data.putExtras(result);

setResult(RESULT_OK, data);

finish();

overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);

});

}

}

// ======================================================

// 文件:res/layout/activity_home.xml

// 作用:首页布局

// ======================================================

android:orientation="vertical" android:layout_width="match_parent"

android:layout_height="match_parent" android:padding="16dp">

android:id="@+id/btnToDetail"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="打开详情页(无参)"/>

android:id="@+id/btnToDetailForResult"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="打开详情页(带参并返回)"/>

// ======================================================

// 文件:res/layout/activity_detail.xml

// 作用:详情页布局

// ======================================================

android:orientation="vertical" android:layout_width="match_parent"

android:layout_height="match_parent" android:padding="16dp">

android:id="@+id/tvInfo"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="详情信息"/>

android:id="@+id/btnFinish"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="返回并携带结果"/>

五、代码解读

RouteConfig:集中定义页面路径与键名常量,避免硬编码字符串和 requestCode 冲突。

Router:封装跳转逻辑,统一管理动画与 Intent 构建,简化调用。

HomeActivity:演示无参跳转与带参跳转并期待结果,回调通过 onActivityResult 分发。

DetailActivity:读取传入参数,渲染 UI,完成后通过 setResult 返回结果。

布局文件:简洁明了,配合 DataBinding 或 ViewBinding 可进一步优化。

六、项目总结与拓展

项目收获

系统理解 Intent、startActivityForResult、FragmentTransaction、Jetpack Navigation 的异同;

掌握参数传递与结果返回的标准流程;

学会封装高复用、易维护的路由工具类;

性能优化

对频繁跳转页面使用 FLAG_ACTIVITY_SINGLE_TOP、launchMode 控制栈行为;

使用 Jetpack Navigation 生成 Safe Args,减少手写 Bundle 错误;

高级拓展

Fragment 跳转:Router 分支支持 NavController.navigate();

深度链接:配置 AndroidManifest 中 ,支持外部链接跳转;

动态权限:跳转前校验所需权限,如相册、摄像头;

跨模块路由:使用 APT 生成跨组件路由表,实现解耦;

上一篇: 快手封号申诉攻略,成功解封不再难(15个步骤教你有效申诉解封快手账号)
下一篇: 小米手机来电铃声为什么改不了 小米手机来电铃声无法更改

相关推荐

华为手机哪款像素最高
【情報】《Mortal Shell》限時免費 @Mortal Shell 哈啦板
抖音一个火箭多少钱人民币?抖音如何快速涨粉?
聚精会神的解释
流量单位换算全攻略:0.01GB到11801MB精准解析
OA办公系统哪个好用?