Fragment 概述:一个“碎片”的诞生

Fragment 是什么?说实话,我刚入行的时候也觉得这玩意儿挺玄乎。

它的中文名叫“碎片”。听着像打碎的零件,对吧?实际上它就是 Android 为了在大屏设备上更好地组织 UI 而造出来的一个组件。说白了,Fragment 就是可以嵌入到 Activity 里的小型模块化界面,有自己的生命周期、能处理自己的输入事件。

我在 2015 年做平板项目时第一次真正体会到它的价值。那时候要在同一个 Activity 里左边显示列表、右边显示详情,写两个 Fragment 来回切换,代码一下子就清爽了。要是全堆在 Activity 里……嗯,那画面我不敢想。

Fragment 的诞生背景

为什么 Google 要搞出 Fragment 来?你想想看,手机屏幕上就那么点地方,Activity 一个界面占满屏,已经够用了。但到了平板、大屏手机,甚至电视上,屏幕变得很大,一个 Activity 只显示一块内容太浪费。而且不同屏幕尺寸下,布局需要灵活调整。

我记得 Android 3.0(Honeycomb)就是针对平板推出的。那时候 Activity 的局限性暴露无遗——无法在同一个 Activity 里同时管理左右两栏的内容。于是 Fragment 应运而生。它允许你把一个 Activity 的界面拆成多个独立的部分,每个部分可以单独控制显示/隐藏、添加/移除。

核心价值:Fragment 让 Activity 从“全屏控制器”变成了“容器”,把视图逻辑和业务逻辑拆分到更小的单元里。

Fragment 与 Activity 的对比

很多人会问:“那我直接用 Activity 不行吗?为什么非要 Fragment?”

答案是:Fragment 比 Activity 更轻量、更灵活。但轻量不等于没代价,它也有自己的坑。我做个对比表,你自己品品:

维度 Activity Fragment
重量级 系统级组件,独立于 manifest 注册 内嵌于 Activity,无需注册
生命周期 由系统管理,对应 Activity 状态变化 依赖宿主 Activity,但拥有自己的完整生命回调
复用性 只能通过 Intent 跳转,无法嵌入 可以在多个 Activity 中复用同一 Fragment
导航 通过 Intent + 任务栈 通过 FragmentManager 管理回退栈
UI 构建 setContentView() 绑定布局 onCreateView() 返回 View
适用场景 全屏独立页面,如登录页、设置页 多面板布局、标签页、可复用组件

我举个例子:比如你做一个新闻 App,首页上方是轮播图、中间是分类 Tab、下面是列表。如果用 Activity 实现,你得把轮播、Tab、列表全塞到一个 Activity 的布局里,耦合度高到爆。如果用 Fragment,每个区域都是一个独立 Fragment,更新轮播图只需要替换那个 Fragment,不会影响其他区域——是不是舒服多了?

Fragment 在 UI 架构中的角色

Fragment 不只是“小 Activity”。它在现代 Android 架构里扮演了三个关键角色:

  • 视图容器:承载具体的布局和 UI 交互逻辑。
  • 生命周期托管者:拥有自己的 LifecycleOwner,配合 LiveData、ViewModel 实现数据分离。
  • 导航单元:作为 Navigation Component 中的 Destination,实现页面跳转和回退。

我曾在一家电商公司重构商城首页,当时首页有十几个区域:搜索、分类、优惠券、秒杀、推荐……如果用 Activity 来完成,那 Activity 的代码至少两千行。后来我把每个区域拆成 Fragment,每个 Fragment 只负责自己的数据和视图,再用一个 FragmentContainerView 把它们组合起来。代码量降了四分之三,而且每个区域可以独立开发和测试。

小心陷阱:Fragment 的“独立”是相对的。它的生命周期与宿主 Activity 深度绑定,Activity 销毁再重建时 Fragment 会被恢复,如果你没有处理好状态保存,就会出现空指针或者 UI 混乱。我有个同事曾经因为 Fragment 的 onSaveInstanceState 没写全,导致横竖屏切换后列表数据丢失——当场差点哭出来。

核心复用场景

Fragment 最大的价值就是复用。我总结了三个最常用的复用模式:

  1. 多面板布局(主从模式):同一份数据用两个 Fragment 展示,一个负责列表,一个负责详情。手机端只显示列表平板端同时显示两者。
  2. Tab 切换:每个 Tab 页是一个 Fragment,通过 ViewPager 或 ViewPager2 滑动切换。
  3. Popup / BottomSheet 内容:把弹窗内的复杂表单或信息展示封装成 Fragment,实现复用的同时保留生命周期管理。

说到 Tab 切换,我记得之前有个需求,底部导航栏有四个页面,每个页面内部又有三四个子 Tab。如果用 Activity 套 Activity……那栈管理会乱成麻。最后我全部用 Fragment 嵌套 Fragment,配合 NavHost + BottomNavigationView,再也不用操心返回逻辑了。

Fragment 知识体系结构图 Fragment 生命周期管理 宿主 Activity 依赖 跨界面复用能力 onCreate / onViewCreated onStart / onResume Activity 重建恢复 FragmentManager 操作 多面板布局 Tab 切换 重点:Fragment 是 Activity 内部的可复用模块,拥有独立生命周期。

个人习惯:我现在写新项目,只要一个界面里有超过两个独立区域,我就会优先考虑用 Fragment 而不是自定义 View。原因很简单——Fragment 自带生命周期和状态管理,省去了一大堆手动 onAttachedToWindow / onDetachedFromWindow 的麻烦。

总体来说,Fragment 是 Android 多屏幕适配和模块化开发的基石。你完全可以把它理解成“Activity 的副驾驶”——帮你分担 UI 和逻辑压力。但副驾驶也要遵守交通规则,后面我们会聊到怎么安全地操纵导航栈、避免 Fragment 复用时的状态混乱。嗯,先从理解它的本质开始吧。