Android Fragment总结
本文总结了Android Fragment的核心知识点。Fragment是可嵌入Activity的UI组件,具有独立布局和生命周期,包括onAttach()到onDetach()等11个关键方法。创建方式分为静态(XML)和动态(代码)两种,推荐使用FragmentContainerView作为容器。FragmentTransaction支持添加、替换、移除等操作。Fragment间通信通常通过A
·
文章目录
Android Fragment总结
概述
Fragment 是一种可以嵌入到 Activity 中的 UI 组件,它具有自己的布局和生命周期。Fragment 代表 Activity 中的行为或用户界面部分,一个 Activity 可以包含多个 Fragment。
生命周期

| 生命周期方法 | 调用时机 | 作用 |
|---|---|---|
| onAttach() | Fragment 与 Activity 关联时 | 获取 Activity 引用 |
| onCreate() | Fragment 创建时 | 初始化非UI资源 |
| onCreateView() | 创建 Fragment 视图时 | 加载布局文件 |
| onViewCreated() | 视图创建完后 | 初始化视图组件 |
| onStart() | Fragment 可见时 | 准备与用户交互 |
| onResume() | Fragment 可交互时 | 开始与用户交互 |
| onPuase() | Fragment 不可交互时 | 保存关键数据 |
| onStop() | Fragment 不可见时 | 释放不重要资源 |
| onDestroyView() | 视图被销毁时 | 清理视图相关资源 |
| onDestroy() | Fragment 被销毁时 | 清理所有资源 |
| onDetach() | 与 Activity 解除关联时 | 清理与 Activity 的引用 |
创建Fragment
静态创建
创建Fragment:
class MyFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_my, container, false)
}
}
静态添加Fragment:
<fragment
android:name="com.test.myapplication.MyFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
动态创建
定义布局容器(传统方式使用FrameLayout):
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
定义布局容器(推荐使用FrameLayout):
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
动态添加Fragment:
class MainActivity : AppCompatActivity() {
private lateinit var myFragment: MyFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
myFragment = MyFragment()
supportFragmentManager.beginTransaction()
.add(R.id.fragment_container, myFragment)
.commit()
} else {
myFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as MyFragment
}
}
}
事务操作
- add():添加 Fragment
- replace():替换 Fragment
- remove():移除 Fragment
- show():显示之前隐藏的 Fragment
- hide():隐藏 Fragment
// 添加Fragment
supportFragmentManager.beginTransaction()
.add(R.id.fragment_container, myFragment)
.commit()
// 替换Fragment
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, myFragment)
.commit()
// 移除Fragment
supportFragmentManager.beginTransaction()
.remove(myFragment)
.commit()
Fragment之间通信
通过Activity
定义接口:
interface OnDataChangeListener {
fun onDataChange(data: String)
}
定义发送方Fragment:
class OneFragment : Fragment() {
private lateinit var listener: OnDataChangeListener
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnDataChangeListener) {
listener = context
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_one, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val btn = view.findViewById<Button>(R.id.btn)
btn.setOnClickListener {
sendData("hello world")
}
}
// 发送数据
private fun sendData(data: String) {
listener.onDataChange(data)
}
}
定义接收方Fragment:
class TwoFragment : Fragment() {
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_two, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
textView = view.findViewById<TextView>(R.id.textView)
}
fun receiveData(data: String) {
textView.text = data
}
}
Activity实现接口:
class MainActivity : AppCompatActivity(), OnDataChangeListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.beginTransaction()
.add(R.id.fragment_container1, OneFragment())
.add(R.id.fragment_container2, TwoFragment())
.commit()
}
override fun onDataChange(data: String) {
val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container2) as TwoFragment
fragment.receiveData(data)
}
}
通过ViewModel
定义共享的ViewModel:
class SharedViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data = _data
fun sendData(data: String) {
_data.value = data
}
}
定义发送方Fragment:
class OneFragment : Fragment() {
private val sharedViewModel by activityViewModels<SharedViewModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_one, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val btn = view.findViewById<Button>(R.id.btn)
btn.setOnClickListener {
sendData("hello world")
}
}
private fun sendData(data: String) {
sharedViewModel.sendData(data)
}
}
定义接收方Fragment:
class TwoFragment : Fragment() {
private val sharedViewModel by activityViewModels<SharedViewModel>()
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_two, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
textView = view.findViewById<TextView>(R.id.textView)
sharedViewModel.data.observe(viewLifecycleOwner) { data ->
receiveData(data)
}
}
fun receiveData(data: String) {
textView.text = data
}
}
setMaxLifecyle()
setMaxLifecycle() 是 FragmentTransaction 中的一个方法,用于控制 Fragment 的最大生命周期状态。更加精准的控制生命周期,实现对加载资源和释放资源的管理。
class MainActivity : AppCompatActivity() {
private lateinit var oneFragment: OneFragment
private lateinit var twoFragment: TwoFragment
private lateinit var btn: Button
private var currentFragment: Fragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn = findViewById<Button>(R.id.btn)
oneFragment = OneFragment()
twoFragment = TwoFragment()
supportFragmentManager.beginTransaction()
.add(R.id.fragment_container1, oneFragment)
.setMaxLifecycle(oneFragment, Lifecycle.State.RESUMED)
.add(R.id.fragment_container1, twoFragment)
.setMaxLifecycle(twoFragment, Lifecycle.State.STARTED)
.hide(twoFragment)
.commit()
currentFragment = oneFragment
btn.setOnClickListener {
switchFragment()
}
}
private fun switchFragment() {
val transaction = supportFragmentManager.beginTransaction()
if (currentFragment == oneFragment) {
transaction.show(twoFragment)
.setMaxLifecycle(twoFragment, Lifecycle.State.RESUMED)
.hide(oneFragment)
.setMaxLifecycle(oneFragment, Lifecycle.State.STARTED)
currentFragment = twoFragment
} else if (currentFragment == twoFragment) {
transaction.show(oneFragment)
.setMaxLifecycle(oneFragment, Lifecycle.State.RESUMED)
.hide(twoFragment)
.setMaxLifecycle(twoFragment, Lifecycle.State.STARTED)
currentFragment = oneFragment
}
transaction.commit()
}
}
转场动画
传统动画资源
在 anim 目录下定义动画资源:
// enter_from_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000">
<translate
android:fromXDelta="-100%"
android:toXDelta="0%" />
<alpha
android:fromAlpha="0"
android:toAlpha="1.0" />
</set>
// enter_from_right
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000">
<translate
android:fromXDelta="100%"
android:toXDelta="0%" />
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
// exit_to_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000">
<translate
android:fromXDelta="0%"
android:toXDelta="-100%" />
<alpha
android:fromAlpha="1.0"
android:toAlpha="0" />
</set>
// exit_to_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000">
<translate
android:fromXDelta="0%"
android:toXDelta="100%" />
<alpha
android:fromAlpha="1.0"
android:toAlpha="0" />
</set>
使用动画:
supportFragmentManager.beginTransaction()
.setCustomAnimations(
R.anim.enter_from_right,
R.anim.exit_to_left,
R.anim.enter_from_left,
R.anim.exit_to_right
)
.replace(R.id.fragment_container, twoFragment)
.addToBackStack(null)
.commit()
现代转场API
class OneFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 设置退出动画:向左滑出
exitTransition = Slide(Gravity.START).apply {
duration = 300
}
}
}
}
class TwoFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 设置进入动画:从右侧向左滑入
enterTransition = Slide(Gravity.END).apply {
duration = 300
}
}
}
}
更多推荐

所有评论(0)