Fragment #

一、Fragment概述 #

Fragment是Android中的一种可重用组件,可以将其视为Activity中的模块化部分。Fragment拥有自己的布局和生命周期,可以在多个Activity中复用。

1.1 Fragment的特点 #

  • 模块化:将UI和逻辑封装成独立模块
  • 可复用:可以在多个Activity中使用
  • 灵活布局:适应不同屏幕尺寸
  • 生命周期:拥有独立的生命周期

1.2 Fragment的应用场景 #

  • Tab页面切换
  • 主从布局(手机/平板适配)
  • ViewPager页面
  • 底部导航栏

二、Fragment生命周期 #

2.1 生命周期图解 #

text
                    创建
                      │
                      ▼
              ┌───────────────┐
              │  onAttach()   │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onCreate()    │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onCreateView()│
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onViewCreated │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onStart()     │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onResume()    │
              └───────┬───────┘
                      │
                      ▼
                 运行中
                      │
                      ▼
              ┌───────────────┐
              │ onPause()     │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onStop()      │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onDestroyView │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onDestroy()   │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ onDetach()    │
              └───────────────┘

2.2 生命周期方法 #

kotlin
class MyFragment : Fragment() {
    
    override fun onAttach(context: Context) {
        super.onAttach(context)
        Log.d("Fragment", "onAttach")
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("Fragment", "onCreate")
    }
    
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        Log.d("Fragment", "onCreateView")
        return inflater.inflate(R.layout.fragment_my, container, false)
    }
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.d("Fragment", "onViewCreated")
    }
    
    override fun onStart() {
        super.onStart()
        Log.d("Fragment", "onStart")
    }
    
    override fun onResume() {
        super.onResume()
        Log.d("Fragment", "onResume")
    }
    
    override fun onPause() {
        super.onPause()
        Log.d("Fragment", "onPause")
    }
    
    override fun onStop() {
        super.onStop()
        Log.d("Fragment", "onStop")
    }
    
    override fun onDestroyView() {
        super.onDestroyView()
        Log.d("Fragment", "onDestroyView")
    }
    
    override fun onDestroy() {
        super.onDestroy()
        Log.d("Fragment", "onDestroy")
    }
    
    override fun onDetach() {
        super.onDetach()
        Log.d("Fragment", "onDetach")
    }
}

2.3 与Activity生命周期对比 #

Activity Fragment
onCreate() onAttach() -> onCreate() -> onCreateView() -> onViewCreated()
onStart() onStart()
onResume() onResume()
onPause() onPause()
onStop() onStop()
onDestroy() onDestroyView() -> onDestroy() -> onDetach()

三、创建Fragment #

3.1 静态创建 #

在布局文件中直接添加Fragment:

xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <fragment
        android:id="@+id/fragment"
        android:name="com.example.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
        
</LinearLayout>

3.2 动态创建 #

使用FragmentManager动态添加Fragment:

xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
kotlin
class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .add(R.id.container, MyFragment())
                .commit()
        }
    }
}

3.3 Fragment布局文件 #

xml
<!-- res/layout/fragment_my.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment内容" />
        
</LinearLayout>

四、Fragment事务 #

4.1 常用事务操作 #

kotlin
val fragment = MyFragment()
val transaction = supportFragmentManager.beginTransaction()

// 添加Fragment
transaction.add(R.id.container, fragment)

// 替换Fragment
transaction.replace(R.id.container, fragment)

// 移除Fragment
transaction.remove(fragment)

// 隐藏Fragment
transaction.hide(fragment)

// 显示Fragment
transaction.show(fragment)

// 提交事务
transaction.commit()

4.2 添加到返回栈 #

kotlin
supportFragmentManager.beginTransaction()
    .replace(R.id.container, fragment)
    .addToBackStack(null)  // 添加到返回栈
    .commit()

4.3 事务动画 #

kotlin
supportFragmentManager.beginTransaction()
    .setCustomAnimations(
        R.anim.slide_in_right,
        R.anim.slide_out_left,
        R.anim.slide_in_left,
        R.anim.slide_out_right
    )
    .replace(R.id.container, fragment)
    .addToBackStack(null)
    .commit()

4.4 commit vs commitNow #

kotlin
// commit:异步提交,在主线程队列中执行
transaction.commit()

// commitNow:同步提交,立即执行
transaction.commitNow()

// commitAllowingStateLoss:允许状态丢失
transaction.commitAllowingStateLoss()

五、Fragment通信 #

5.1 Fragment与Activity通信 #

通过接口回调 #

kotlin
interface OnFragmentInteractionListener {
    fun onFragmentInteraction(data: String)
}

class MyFragment : Fragment() {
    private var listener: OnFragmentInteractionListener? = null
    
    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is OnFragmentInteractionListener) {
            listener = context
        } else {
            throw RuntimeException("$context must implement OnFragmentInteractionListener")
        }
    }
    
    fun sendData(data: String) {
        listener?.onFragmentInteraction(data)
    }
    
    override fun onDetach() {
        super.onDetach()
        listener = null
    }
}

class MainActivity : AppCompatActivity(), OnFragmentInteractionListener {
    override fun onFragmentInteraction(data: String) {
        // 处理Fragment传来的数据
    }
}

通过ViewModel #

kotlin
class SharedViewModel : ViewModel() {
    private val _data = MutableLiveData<String>()
    val data: LiveData<String> = _data
    
    fun setData(value: String) {
        _data.value = value
    }
}

class MyFragment : Fragment() {
    private val viewModel: SharedViewModel by activityViewModels()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewModel.data.observe(viewLifecycleOwner) { data ->
            // 更新UI
        }
    }
}

class MainActivity : AppCompatActivity() {
    private val viewModel: SharedViewModel by viewModels()
}

5.2 Fragment之间通信 #

通过Activity #

kotlin
class MainActivity : AppCompatActivity() {
    private var fragmentA: FragmentA? = null
    private var fragmentB: FragmentB? = null
    
    fun sendDataToFragmentB(data: String) {
        fragmentB?.receiveData(data)
    }
}

通过ViewModel #

kotlin
// 两个Fragment共享同一个ViewModel
class FragmentA : Fragment() {
    private val viewModel: SharedViewModel by activityViewModels()
    
    fun sendData(data: String) {
        viewModel.setData(data)
    }
}

class FragmentB : Fragment() {
    private val viewModel: SharedViewModel by activityViewModels()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewModel.data.observe(viewLifecycleOwner) { data ->
            // 接收数据
        }
    }
}

5.3 Fragment获取数据 #

kotlin
class MyFragment : Fragment() {
    
    companion object {
        private const val ARG_DATA = "data"
        
        fun newInstance(data: String): MyFragment {
            return MyFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_DATA, data)
                }
            }
        }
    }
    
    private var data: String? = null
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        data = arguments?.getString(ARG_DATA)
    }
}

// 使用
val fragment = MyFragment.newInstance("Hello")

六、Fragment最佳实践 #

6.1 使用viewLifecycleOwner #

kotlin
// 错误:使用Fragment的lifecycleOwner
viewModel.data.observe(this) { }

// 正确:使用viewLifecycleOwner
viewModel.data.observe(viewLifecycleOwner) { }

6.2 避免在构造函数中传递参数 #

kotlin
// 错误:构造函数传参
class MyFragment(private val data: String) : Fragment()

// 正确:使用arguments
companion object {
    fun newInstance(data: String) = MyFragment().apply {
        arguments = Bundle().apply {
            putString("data", data)
        }
    }
}

6.3 正确处理返回键 #

kotlin
class MyFragment : Fragment() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                // 处理返回键
                if (hasUnsavedChanges()) {
                    showConfirmDialog()
                } else {
                    isEnabled = false
                    requireActivity().onBackPressed()
                }
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(this, callback)
    }
}

6.4 使用Fragment Result API #

kotlin
// 发送结果
setFragmentResult("requestKey", bundleOf("data" to "Hello"))

// 接收结果
setFragmentResultListener("requestKey") { requestKey, bundle ->
    val data = bundle.getString("data")
}

七、总结 #

本章详细介绍了Fragment:

  1. Fragment的基本概念和特点
  2. Fragment的生命周期
  3. Fragment的创建方式
  4. Fragment事务操作
  5. Fragment之间的通信
  6. 最佳实践

Fragment是Android开发中的重要组件,合理使用可以实现灵活的界面设计。

最后更新:2026-03-26