删除主机片段时,片段实例保留在 viewPager2 中

Fragment instances are kept in viewPager2 when host fragment removed

有一个 activity 应用程序,其中我有 HomeFragment,我从中打开 HostFragment,而 HostFragment 有 ViewPager2 和 3 个片段项目 TabFragment1、TabFragment2 和 TabFragment3。

当我打开 HostFragment 然后返回时,我的 tabFragments 实例没有被删除。以下是来自 lifecycles

的日志

navController.navigate(directionToHostFragment)

  1. HostFragment OnStart HostFragment{c37542c}
  2. TabFragment1 OnStart TabFragment1 {f41b08}

navController.popBackStack()

  1. HostFragment OnPause HostFragment{c37542c}
  2. HostFragment OnStop{c37542c}
  3. HostFragment OnDestroy {c37542c}

navController.navigate(directionToHostFragment) Blockquote

  1. HostFragment OnStart{2670c03}
  2. TabFragment1 OnStart{f45b87d}

navController.popBackStack()

  1. HostFragment OnPause{2670c03}
  2. HostFragment 停止{2670c03}
  3. HostFragment onDestroy{2670c03}

从ids可以看到有一个新的TabFragment1实例,旧的没有被销毁(我有登录onPause(), onStop()等)。

一些代码片段: 我使用的 viewPager2 适配器 -

class LessonTabsAdapter(fragmentActivity: FragmentActivity, val pages: List<BaseFragment>) :
    FragmentStateAdapter(fragmentActivity) {
    override fun getItemCount() = pages.size
    override fun createFragment(position: Int) = pages[position]
}

TabFragment1 的部分内容

class TabFragment1 : BaseFragment(R.layout.fragment_tab_1) {
    private var mediaPlayer: MediaPlayerClass? = null
    private lateinit var player: SimpleExoPlayer

    private val viewModel by sharedViewModel<SomeViewModel>()
    private val binding by viewDataBinding(FragmentTab1Binding::bind)
    //Overriden onViewCreated(..) and some private methods 
}

那么有什么提示可以解决这个问题吗?

当您打开 HostFragment 时,ViewPager2 在提供的生命周期中创建一个片段。在这种情况下,您将 activity 作为参数传递,因此它会在 Activity's 生命周期中创建片段。您可以通过打印 activity?.supportFragmentManager?.fragments 列表进行检查。如果您想将 ViewPager2 的孩子与 HostFRagment 耦合,您需要将片段实例传递给 FragmentStateAdapter。检查我添加的函数2。实现 ViewPager2 的最佳方法是使用函数 3.

1..
public FragmentStateAdapter(@NonNull FragmentActivity fragmentActivity) {
  this(fragmentActivity.getSupportFragmentManager(),fragmentActivity.getLifecycle());
}

2.//
public FragmentStateAdapter(@NonNull Fragment fragment) {
  this(fragment.getChildFragmentManager(), fragment.getLifecycle());
}

3.//
public FragmentStateAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
   mFragmentManager = fragmentManager;
   mLifecycle = lifecycle;
   super.setHasStableIds(true);
}