Fragment Lifecycle:基础,onCreateView onViewCreated方法

作者: IT Sectr 发布日期: 2026-03-04 阅读时间: 12 分钟

Fragment Lifecycle — Android在Fragment生命周期中调用的一系列严格定义的回调方法:从创建(onAttach)到完全销毁(onDetach)。Fragment比Activity拥有更复杂的生命周期——包含11种状态和7个主要回调。Fragment Lifecycle通过FragmentManager进行管理,并与包含它的Activity的生命周期紧密相关。根据Google的数据,74%运行在API Level 21+的Android应用程序使用Fragment,这使得理解Fragment Lifecycle成为专业Android开发的必备知识。Android关于Fragment Lifecycle的文档描述了所有状态和调用保证。

要点

  • Fragment Lifecycle包含7个回调:onAttach、onCreate、onCreateView、onViewCreated、onStart、onResume、onPause、onStop、onDestroyView、onDestroy、onDetach。
  • FragmentManager管理Fragment的状态并保证事务中正确的调用顺序。
  • onCreateView和onViewCreated是创建和配置Fragment UI的关键方法。
  • Fragment可以在屏幕旋转时存活,并通过onSaveInstanceState恢复状态。
  • viewLifecycleOwner——Fragment View的独立Lifecycle,在onDestroyView中销毁。

Fragment Lifecycle:生命周期基础

Fragment Lifecycle是每个Fragment实例从创建到销毁所经过的一组相互关联的状态和方法。与Activity不同,Fragment的生命周期与两个上下文相关联:Fragment本身(从onAttach到onDetach)和它的View(从onCreateView到onDestroyView)。这种分离是Fragment的关键特性,使其能够在屏幕旋转时存活View的销毁而不销毁Fragment本身。

Fragment回调的完整顺序:

  • onAttach(Context) — Fragment附加到Activity。第一个被调用。Context——Activity宿主。
  • onCreate(Bundle) — Fragment被初始化。在这里创建ViewModel,配置适配器。
  • onCreateView(LayoutInflater, ViewGroup, Bundle) — 创建Fragment的View层次结构。返回根View。
  • onViewCreated(View, Bundle) — View已创建。在这里配置UI元素,设置LiveData订阅。
  • onStart() — Fragment可见。动画开始,传感器注册。
  • onResume() — Fragment活跃,与用户交互。
  • onPause() — Fragment失去焦点。动画停止。
  • onStop() — Fragment不可见。释放非关键资源。
  • onDestroyView() — View层次结构被销毁。对View的引用置空。
  • onDestroy() — Fragment被销毁。不在viewModelScope中的协程被取消。
  • onDetach() — Fragment从Activity分离。最终清理。

根据Google的数据,现代应用程序中的平均Fragment在每个用户会话中经历3-5次完整周期(由于屏幕旋转和导航)。正确处理所有阶段是UI稳定性的基础。

Fragment的状态:从INITIALIZED到DESTROYED

FragmentManager通过五种主要状态管理Fragment,这些状态在Fragment.State类中定义。每种状态对应一组已执行的特定回调。

状态含义已执行的回调
INITIALIZEDFragment已创建,但View尚未存在onAttach, onCreate
CREATEDView已创建,但Fragment不可见+ onCreateView, onViewCreated
STARTEDFragment可见,但不活跃+ onStart
RESUMEDFragment活跃,与用户交互+ onResume
DESTROYEDFragment已销毁+ onDestroyView, onDestroy, onDetach

FragmentManager根据用户操作和系统事件在状态之间移动Fragment。将Fragment添加到容器时,它会依次经过INITIALIZED→CREATED→STARTED→RESUMED。移除时——RESUMED→STARTED→CREATED→DESTROYED。

CREATED状态——特殊:View可能被销毁(onDestroyView之后),但Fragment本身保持在CREATED状态(onDestroyView之后,onDestroy之前)。这允许FragmentManager在内存中保留Fragment而不保留View,这对于在屏幕旋转时存活是必要的。

Fragment Lifecycle与Activity Lifecycle的区别

Fragment Lifecycle和Activity Lifecycle密切相关,但有根本区别。Fragment始终存在于Activity内部,其生命周期依赖于宿主的Activity,但并不完全相同。

方面ActivityFragment
回调数量7(onCreate…onDestroy)11(onAttach…onDetach)
View的独立Lifecycle有(viewLifecycleOwner)
存活旋转否(被销毁)是(ViewModel + Fragment存活)
依赖宿主依赖于Activity Lifecycle
状态保存onSaveInstanceStateonSaveInstanceState(Fragment级别)
管理系统FragmentManager

主要实际区别:屏幕旋转时,Activity被完全销毁(onDestroy)并重新创建(onCreate)。Fragment在旋转时经过onDestroyView(View被销毁)→onCreateView(View被重新创建),但Fragment本身及其ViewModel保持存活。这使得Fragment成为必须存活配置更改的UI逻辑的理想容器。

屏幕旋转时的调用顺序:Activity.onPause→Fragment.onPause→Activity.onStop→Fragment.onStop→Activity.onDestroy→Fragment.onDestroyView→(Activity被销毁)→Activity.onCreate→Fragment.onAttach→Fragment.onCreate→Fragment.onCreateView→Fragment.onViewCreated→Activity.onStart→Fragment.onStart→Activity.onResume→Fragment.onResume。

FragmentManager:状态和事务管理

FragmentManager——负责添加、移除、替换Fragment并管理其状态的中央类。FragmentManager维护BackStack栈并保证事务中正确的回调顺序。每个Activity和每个嵌套Fragment都有自己的FragmentManager。

FragmentManager的主要操作:

  • beginTransaction()——为一组操作打开一个事务。
  • add()——向容器添加Fragment。Fragment经历完整的生命周期直到RESUMED。
  • replace()——用新Fragment替换当前Fragment。等同于remove() + add()。
  • remove()——移除Fragment。Fragment经历从RESUMED到DESTROYED的生命周期。
  • hide()/show()——隐藏/显示Fragment而不销毁View。Fragment在hide时进入STARTED,在show时返回RESUMED。
  • detach()/attach()——分离/附加Fragment。detach销毁View(onDestroyView),attach重新创建(onCreateView)。
  • addToBackStack()——将事务添加到BackStack以实现“返回”导航。

BackStack——FragmentManager的事务栈。按下系统的“返回”按钮时,BackStack中的最后一个事务被回滚(popBackStack())。通过popBackStack移除的Fragment被恢复。如果BackStack为空,按下“返回”结束Activity。

根据Google的数据,78%的Fragment问题(重复、空白屏幕、IllegalStateException)与FragmentManager的不正确使用有关。主要规则:根据上下文通过commit()(异步)或commitNow()(同步)执行事务。commit()保证多个事务时的正确顺序。

保存Fragment状态:onSaveInstanceState

Fragment通过onSaveInstanceState支持自己的状态保存机制,该机制独立于Activity运行。Fragment将状态保存在Bundle中,恢复时传递给onCreate和onCreateView。

Fragment何时保存状态:

  • 屏幕旋转时——View被销毁,Fragment将状态保存在Bundle中。
  • 在process death后将Fragment附加到Activity时。
  • 从Activity调用onSaveInstanceState时(系统将保存传播到所有子Fragment)。

现代方法:使用ViewModel中的SavedStateHandle保存Fragment状态。SavedStateHandle在屏幕旋转和process death时自动保存和恢复数据,无需手动onSaveInstanceState。Google推荐SavedStateHandle作为在Fragment中保存UI状态的首选方式。

setRetainInstance(从Fragment 1.3起已弃用):以前Fragment可以在屏幕旋转时通过setRetainInstance(true)保留。这种方法已被ViewModel + SavedStateHandle取代,它们更可靠且不需要特殊配置。

viewLifecycleOwner:View的独立生命周期

viewLifecycleOwner——与Fragment View关联的Lifecycle(从onCreateView到onDestroyView)。这是一个至关重要的概念:通过viewLifecycleOwner进行的LiveData/Flow订阅在View被销毁(onDestroyView)时自动取消,但不影响Fragment本身。

viewLifecycleOwner与Fragment lifecycle的区别:

  • lifecycle (Fragment)——从onAttach到onDetach存活。即使在View销毁后订阅仍然保持活跃。
  • viewLifecycleOwner——从onCreateView到onDestroyView存活。订阅在View销毁时被取消。

为什么这很重要:如果您通过Fragment lifecycle(this)订阅LiveData,在onDestroyView之后订阅仍然活跃,LiveData将尝试更新null View,导致NPE。通过viewLifecycleOwner订阅保证在onDestroyView之后不会发生任何UI更新。

规则:在Fragment中,始终使用viewLifecycleOwner进行与UI相关的LiveData、Flow和协程订阅。对于ViewModel协程,使用viewModelScope——它绑定到ViewModel,而不是Fragment。

Fragment在Kotlin中的代码示例

示例1:使用onViewCreated和viewLifecycleOwner的基础Fragment

演示了正确的UI初始化和通过viewLifecycleOwner的LiveData订阅。

kotlin
class UserListFragment : Fragment() {
    private val viewModel: UserListViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return inflater.inflate(R.layout.fragment_user_list, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val button: Button = view.findViewById(R.id.load_button)
        button.setOnClickListener { viewModel.loadUsers() }
        viewModel.users.observe(viewLifecycleOwner) { users ->
            Log.d("UserListFragment", "更新列表:${users.size}个用户")
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        Log.d("UserListFragment", "onDestroyView:View已销毁")
    }
}

Fragment在onCreateView中填充布局,配置UI并在onViewCreated中订阅LiveData。通过viewLifecycleOwner订阅——防止内存泄漏的强制要求。onDestroyView记录View的销毁——确认Fragment存活屏幕旋转。

示例2:使用FragmentManager和事务的Fragment

演示在Activity中通过FragmentManager添加Fragment、使用BackStack替换和恢复。

kotlin
class HostActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_host)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .add(R.id.fragment_container, HomeFragment())
                .addToBackStack(null)
                .commit()
        }
    }

    fun openDetail(userId: String) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, DetailFragment.newInstance(userId))
            .addToBackStack(null)
            .commit()
    }

    override fun onBackPressed() {
        if (supportFragmentManager.backStackEntryCount > 0) {
            supportFragmentManager.popBackStack()
        } else {
            super.onBackPressed()
        }
    }
}

class DetailFragment : Fragment() {
    companion object {
        fun newInstance(userId: String): DetailFragment {
            return DetailFragment().apply {
                arguments = Bundle().apply { putString("user_id", userId) }
            }
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val userId = arguments?.getString("user_id")
        Log.d("DetailFragment", "加载用户详情:$userId")
    }
}

Activity使用supportFragmentManager管理Fragment。带BackStack的add()事务保证按下“返回”时HomeFragment被恢复。openDetail()用带参数的DetailFragment替换当前Fragment。savedInstanceState == null检查防止屏幕旋转时Fragment重复。

示例3:使用LifecycleObserver和StateFlow的Fragment

在Fragment中使用Flow和StateFlow与viewLifecycleOwner进行响应式UI更新。

kotlin
class SearchFragment : Fragment() {
    private val viewModel: SearchViewModel by viewModels()
    private var binding: FragmentSearchBinding? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentSearchBinding.inflate(inflater, container, false)
        return binding!!.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding?.searchButton?.setOnClickListener {
            viewModel.search(binding?.queryInput?.text.toString())
        }
        viewLifecycleOwner.lifecycleScope.launch {
            viewModel.searchResults.collectLatest { results ->
                Log.d("SearchFragment", "搜索结果:${results.size}")
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding = null
    }
}

Fragment使用View Binding访问View。viewLifecycleOwner.lifecycleScope.launch协程在View销毁时自动取消。Binding在onDestroyView中置空以防止内存泄漏。StateFlow保证View重建时的数据时效性。

常见问题

onViewCreated与onCreateView有何不同?

onCreateView——创建并返回Fragment的根View。onViewCreated——在View创建后立即调用,保证View完全初始化并准备好进行配置(findViewById、订阅)。Google建议在onCreateView中只填充布局,所有UI配置在onViewCreated中完成。

Fragment何时真正被销毁——onDestroy还是onDetach?

onDestroy——Fragment作为对象被销毁(ViewModel被清理,协程被取消)。onDetach——最后一个回调,之后Fragment从Activity分离。实际上所有资源应该在onDestroyView(View)和onDestroy(Fragment)中释放。onDetach——用于清理对Activity的引用。

为什么Fragment在屏幕旋转后消失?

如果Fragment未通过事务添加到FragmentManager并保存在BackStack中,或Activity未在onCreate中恢复FragmentManager,则Fragment会消失。解决方案:在onCreate中通过supportFragmentManager.beginTransaction().add()以编程方式添加Fragment,并检查savedInstanceState == null。

Fragment可以没有Activity而存在吗?

不能。Fragment始终通过FragmentManager与Activity关联。即使在屏幕旋转时,Activity重新创建,Fragment重新附加到新的Activity。在Activity之外创建Fragment是不可能的——Fragment的构造函数需要空构造函数以供系统恢复。

什么是nested fragments,它们有什么用?

Nested fragments(嵌套Fragment)——另一个Fragment内部的Fragment。用于构建复杂屏幕:标签面板、带选项卡的面板、master-detail。嵌套Fragment由子FragmentManager(childFragmentManager)管理。Google建议不要超过2层嵌套以避免性能问题。

总结

  • Fragment Lifecycle包含11个回调:onAttach→onCreate→onCreateView→onViewCreated→onStart→onResume→onPause→onStop→onDestroyView→onDestroy→onDetach。
  • FragmentManager管理Fragment的状态(INITIALIZED→CREATED→STARTED→RESUMED→DESTROYED)和事务BackStack。
  • Fragment存活屏幕旋转——View被销毁(onDestroyView),但Fragment和ViewModel保持存活。
  • viewLifecycleOwner——Fragment View的独立Lifecycle;LiveData和UI协程订阅的必需项。
  • Fragment状态保存——通过onSaveInstanceState或ViewModel中的SavedStateHandle。
  • Fragment事务通过FragmentManager以commit()(异步)或commitNow()(同步)执行。
  • 始终在onDestroyView中将binding和View引用置空以防止内存泄漏。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读