Fragment
模块化
fragment 允许您将界面划分为离散的区块,从而将模块化和可重用性引入 activity 的界面。activity 是围绕应用的界面放置全局元素(如抽屉式导航栏)的理想位置。相反,Fragment 更适合定义和管理单个屏幕或部分屏幕的界面。
假设有一个响应各种屏幕尺寸的应用。在大屏设备上,您可能希望应用以网格布局显示静态抽屉式导航栏和列表。在小屏设备上,您可能希望应用以线性布局显示底部导航栏和列表。
在 activity 中管理这些变体非常麻烦。将导航元素与内容分离可使此过程更易于管理。然后,activity 负责显示正确的导航界面,而 fragment 采用适当的布局显示列表。
图 1. 同一屏幕的采用不同屏幕尺寸的两个版本。在左侧,大屏幕包含一个由 activity 控制的抽屉式导航栏和一个由 fragment 控制的网格列表。在右侧,小屏幕包含一个由 activity 控制的底部导航栏和一个由 fragment 控制的线性列表。
将界面划分为 fragment 可让您更轻松地在运行时修改 activity 的外观。当 activity 处于 STARTED
生命周期状态或更高的状态时,可以添加、替换或移除 fragment。此外,您可以将这些更改的记录保留在由 activity 管理的返回堆栈中,以便撤消这些更改。
您可以在同一 activity 或多个 activity 中使用同一 fragment 类的多个实例,甚至可以将其用作另一个 fragment 的子级。考虑到这一点,请仅为 fragment 提供管理其自身界面所需的逻辑。避免让一个 fragment 依赖于另一个 fragment 或从一个 fragment 操控另一个 fragment。
bookmark_border
Fragment
表示应用界面中可重复使用的一部分。fragment 定义和管理自己的布局,具有自己的生命周期,并且可以处理自己的输入事件。fragment 不能独立存在。它们必须由 activity 或其他 fragment 托管。fragment 的视图层次结构会成为宿主的视图层次结构的一部分,或附加到宿主的视图层次结构。
fragment 生命周期
每个 Fragment
实例都有自己的生命周期。当用户浏览您的应用并与之互动时,您的 Fragment 会在添加、移除时以及进入或退出屏幕时完成其生命周期内各种状态的转换。
为了管理生命周期,Fragment
会实现 LifecycleOwner
,公开可通过 getLifecycle()
方法访问的 Lifecycle
对象。
每种可能的 Lifecycle
状态均在 Lifecycle.State
枚举中表示。
通过在 Lifecycle
的基础上构建 Fragment
,您能够受益于那些可助您实现使用生命周期感知型组件处理生命周期的技术和类。例如,您可以使用生命周期感知型组件在屏幕上显示设备的位置。当 Fragment 转为活跃状态时,此组件会自动开始监听,当 Fragment 转为非活跃状态时,此组件会自动停止监听。
作为使用 LifecycleObserver
的替代方法,Fragment
类包含与 Fragment 生命周期中每项变化相对应的回调方法。其中包括 onCreate()
、onStart()
、onResume()
、onPause()
、onStop()
和 onDestroy()
。
Fragment 的视图有一个单独的 Lifecycle
,独立于 Fragment 的 Lifecycle
进行管理。Fragment 为其视图维护一个 LifecycleOwner
,可使用 getViewLifecycleOwner()
或 getViewLifecycleOwnerLiveData()
进行访问。如果生命周期感知型组件只应在 Fragment 的视图存在时执行工作(例如观察只是为了在屏幕上显示的 LiveData
),那么有权访问视图的 Lifecycle
会很有用。
本主题详细讨论了 Fragment
生命周期,介绍了一些确定 Fragment 生命周期状态的规则,并展示了 Lifecycle
状态与 Fragment 生命周期回调之间的关系。
代码解析
/**
在Fragment中创建并返回视图的方法。
@param inflater 用于从XML布局文件中创建视图的布局填充器。
@param container 父视图的容器,如果有的话,可以用于确定新创建的视图应该附加到哪个父视图。
@param savedInstanceState 保存Fragment状态信息的Bundle对象,用于在Fragment重新创建时恢复状态。
@return 创建的Fragment视图对象。 */ @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 在这里使用布局填充器将XML布局文件转换为视图对象 View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
// 在这里可以对视图进行初始化和设置,例如设置监听器、初始化控件等 // rootView.findViewById(R.id.someView).setOnClickListener(this);
// 返回创建的视图对象作为Fragment的根视图 return rootView; }
其中bundle
Bundle
是Android中用于传递数据的一种数据结构,它允许你在不同的组件(例如Activity、Fragment、Service等)之间传递数据和状态信息。
具体来说,Bundle
有以下几个作用:
- 传递数据 :你可以将各种类型的数据存储在Bundle中,例如基本类型数据(int、boolean、String等)、Parcelable对象、Serializable对象等。然后,你可以将这个Bundle对象传递给其他组件,使得这些组件可以获取并使用这些数据。
- 保存状态信息 :在Android应用中,组件的状态会因为各种原因(例如屏幕旋转、后台运行时被系统杀死等)而发生改变。通过将数据保存在Bundle中,并将Bundle与组件的生命周期相关联,你可以在组件重新创建时恢复之前的状态信息,以确保用户体验的连续性。
- 安全传递数据 :Bundle的设计考虑了Android应用的安全性,因此可以安全地传递敏感数据,例如用户凭证、加密密钥等。