删除主机片段时,片段实例保留在 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)
- HostFragment OnStart HostFragment{c37542c}
- TabFragment1 OnStart TabFragment1 {f41b08}
navController.popBackStack()
- HostFragment OnPause HostFragment{c37542c}
- HostFragment OnStop{c37542c}
- HostFragment OnDestroy {c37542c}
navController.navigate(directionToHostFragment)
Blockquote
- HostFragment OnStart{2670c03}
- TabFragment1 OnStart{f45b87d}
navController.popBackStack()
- HostFragment OnPause{2670c03}
- HostFragment 停止{2670c03}
- 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);
}
有一个 activity 应用程序,其中我有 HomeFragment,我从中打开 HostFragment,而 HostFragment 有 ViewPager2 和 3 个片段项目 TabFragment1、TabFragment2 和 TabFragment3。
当我打开 HostFragment 然后返回时,我的 tabFragments 实例没有被删除。以下是来自 lifecycles
的日志navController.navigate(directionToHostFragment)
- HostFragment OnStart HostFragment{c37542c}
- TabFragment1 OnStart TabFragment1 {f41b08}
navController.popBackStack()
- HostFragment OnPause HostFragment{c37542c}
- HostFragment OnStop{c37542c}
- HostFragment OnDestroy {c37542c}
navController.navigate(directionToHostFragment) Blockquote
- HostFragment OnStart{2670c03}
- TabFragment1 OnStart{f45b87d}
navController.popBackStack()
- HostFragment OnPause{2670c03}
- HostFragment 停止{2670c03}
- 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);
}