Fragment — Android中可重用的UI组件,嵌入到Activity中并通过FragmentManager管理。每个Fragment都有自己的生命周期、布局和状态。Fragment简化了不同屏幕尺寸的适配和代码复用。更多信息请阅读Google官方指南。
要点
Fragment — 模块化的Android用户界面组件,代表Activity内部屏幕的一部分。Fragment可以管理自己的布局、处理生命周期事件并保存其状态。由于模块化,一个Fragment可以在不同的Activity和不同的设备上使用。
Fragment API于2011年在Android 3.0(Honeycomb,API 11)中引入,用于支持平板电脑。在此之前,开发人员必须为手机和平板电脑创建单独的Activity。Fragment使得可以从独立块组装屏幕。2019年,Google发布了向后兼容至API 4的Jetpack Fragment库。
根据Google的数据(2026),Google Play中80%的应用以某种形式使用Fragment。Jetpack Fragment库通过Google Play Services被下载超过100亿次。即使在Jetpack Compose时代,Fragment仍然是Android架构的关键组件。
Fragment的生命周期比Activity更复杂,因为它依赖于宿主Activity的状态。Fragment经历与Activity相同的状态,但添加了自己的回调:onAttach、onCreateView、onViewCreated、onActivityCreated、onDestroyView、onDetach。
| Fragment回调 | 对应的Activity | 用途 |
|---|---|---|
| onAttach | onCreate之前 | Fragment已附加到Activity |
| onCreate | onCreate | 初始化与UI无关的数据 |
| onCreateView | onCreate | 通过inflater创建布局 |
| onViewCreated | onCreate | 在创建视图后绑定UI元素 |
| onDestroyView | onDestroy | 移除视图,释放UI资源 |
| onDetach | onDestroy | Fragment已从Activity分离 |
Fragment生命周期的主要区别——在onCreate和onDestroy之间调用onCreateView和onDestroyView。Fragment可以在没有UI的情况下存在(如果onCreateView返回null)。在Activity重新创建后,FragmentManager会自动恢复Fragment。
FragmentManager — 在Activity中管理Fragment的核心类。负责添加、删除、替换Fragment,管理返回栈和恢复状态。FragmentManager可以通过supportFragmentManager(AndroidX)或fragmentManager(旧API)访问。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 如果Fragment尚未添加——我们创建
if (savedInstanceState == null) {
val transaction = this.supportFragmentManager
.beginTransaction()
transaction.add(R.id.fragment_container, ListFragment())
transaction.addToBackStack(null)
transaction.commit()
}
}
fun replaceFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit()
}
}FragmentTransaction的事务——是原子的。commit()计划在下一个Looper循环执行。要立即执行,请使用commitNow()。addToBackStack(null)将事务添加到返回栈——「返回」按钮将撤销操作。
让我们通过Kotlin示例来了解Fragment生命周期的关键方法。onCreateView创建布局——与Activity不同,该方法必须返回View。onViewCreated紧随其后被调用,在这里可以根据id安全地查找元素。onDestroyView——清理视图引用的最后时机。
class DetailFragment : Fragment() {
private var _binding: FragmentDetailBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentDetailBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.textTitle.setText("详情")
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}使用_binding/binding的View Binding模式保证在onDestroyView之后布局引用被置空。在视图销毁后访问binding将导致NullPointerException。Google建议对所有Fragment使用此模式。
对于Fragment之间的数据传输,Android提供了多种机制。最可靠的是——共享的ViewModel,在同一Activity的Fragment之间共享。Fragment Result API适用于一次性事件。Bundle参数——用于创建Fragment时的数据。
// 两个Fragment共享的ViewModel
class SharedViewModel : ViewModel() {
private val _selectedItem = MutableLiveData<Item>()
val selectedItem: LiveData<Item> = _selectedItem
fun select(item: Item) { _selectedItem.setValue(item) }
}
// Fragment A:通过Fragment Result API发送事件
setFragmentResult("request_key", bundleOf("key" to "value"))
// Fragment B:接收事件
childFragmentManager.setFragmentResultListener("request_key", this) { requestKey, bundle ->
val value = bundle.getString("key")
}Fragment Result API(在Fragment 1.3.0中添加)取代了已废弃的setTargetFragment/onActivityResult。API是类型安全的,使用Bundle,并且不需要了解接收者。Parent FragmentManager充当Fragment之间的中介。
选择Fragment还是Activity取决于应用程序的架构。Fragment对于自适应布局(手机+平板)、自定义过渡动画和使用Jetpack Navigation是必需的。Activity对于具有一到两个屏幕的简单应用更可取。
| 标准 | Fragment | Activity |
|---|---|---|
| 创建速度 | 更快(轻量组件) | 更慢(系统进程) |
| 可重用性 | 高(一个Fragment在不同Activity中) | 低(每个屏幕有自己的Activity) |
| 过渡动画 | 灵活(FragmentTransaction) | 有限(overridePendingTransition) |
| 旋转时保存 | 自动(管理器恢复) | 手动(onSaveInstanceState) |
| 深度链接 | 通过Navigation Component | 通过intent-filter的原生支持 |
使用Fragment的现代方法是——Jetpack Navigation Component,它取代了手动管理FragmentManager。该库提供了NavGraph(XML导航图)、NavHostFragment和用于类型安全数据传输的Safe Args。
Jetpack Fragment库(androidx.fragment:fragment-ktx)包括FragmentResult API、DialogFragment、BottomSheetDialogFragment以及与Lifecycle-aware组件的集成。自2026年起,Google建议仅通过Jetpack Navigation使用Fragment,而不是直接使用。
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@+id/listFragment">
<fragment
android:id="@+id/listFragment"
android:name=".ListFragment"
android:label="列表">
<action
android:id="@+id/action_list_to_detail"
app:destination="@+id/detailFragment" />
</fragment>
<fragment
android:id="@+id/detailFragment"
android:name=".DetailFragment"
android:label="详情" />
</navigation>常见问题
FragmentManager — 管理Fragment事务的类。它在Activity容器中添加、删除、替换Fragment。FragmentManager在Activity重新创建时恢复Fragment的状态并管理返回栈。
Fragment — Activity内部的UI部分,不能独立存在。Fragment在屏幕旋转时能够存活于Activity的重新创建。Activity — 拥有自己Lifecycle的完整屏幕,Fragment依赖于Activity的Lifecycle。
Fragment — 当屏幕由多个独立块组成时(标签页、主从视图、平板适配)。Activity — 当屏幕没有重复块时。Google建议使用Single Activity + 多个Fragment。
三种方式:通过父Activity(共享ViewModel),通过Fragment Result API(setFragmentResult),通过创建Fragment时的Bundle参数。ViewModel是首选方式,因为数据在重新创建时会保留。
Fragment Transaction — 更改Fragment集合的原子操作。FragmentManager.beginTransaction()打开一个事务,在其中可以调用add、remove、replace、hide、show。每个事务以commit()或commitNow()结束。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。