使用 ViewPager2 和 FragmentStateAdapter 的片段生命周期行为
Posted
技术标签:
【中文标题】使用 ViewPager2 和 FragmentStateAdapter 的片段生命周期行为【英文标题】:Fragment lifecylce behaviour using ViewPager2 and FragmentStateAdapter 【发布时间】:2020-06-12 12:57:45 【问题描述】:我使用ViewPager2
和FragmentStateAdapter
显示5 个fragments
。每个fragment
都有ExoPlayer
实例。我正在维护ViewPager2.setOffscreenPageLimit(1)
,它可以很好地加载fragments
。但是,当我将ViewPager2
向下滚动到pos4
时,pos2
和pos1
应该调用onStop()
、onDestroyView()
、onDestroy()
。但这并没有发生。
除非我按onBackPress()
,否则这些方法都不会执行。 FragmentStateAdapter
的实现部分有什么我遗漏的吗?
我想对onDestroyView()
执行exoPlayer.release()
以释放应用程序的内存。
这里是代码
活动
List<Post> postsList = response.getPosts();
ViewPagerAdapter adapter = new ViewPagerAdapter(this, postsList);
binding.pager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
binding.pager.setOffscreenPageLimit(1);
binding.pager.setAdapter(adapter);
ViewPagerAdapter
public class ViewPagerAdapter extends FragmentStateAdapter
private List<Post> postList;
public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity, List<Post> postList)
super(fragmentActivity);
this.postList = postList;
@NonNull
@Override
public Fragment createFragment(int position)
return new PostFragment(postList.get(position), position);
@Override
public int getItemCount()
if (postList == null) return 0;
return postList.size();
更新
This is also a similar question
【问题讨论】:
您是否尝试在 onDestroy 而不是 onDestroyView 中释放 exo 播放器实例? @ParagPawar 我删除了以前的 cmets 以避免混淆。最后,我得到了一个令人满意的解决方案。请参考答案:) 【参考方案1】:我已将此 POST 转介给解决方案。
VeiwPager2
建立在 RecyclerView
组件之上,FragmentStateAdapter
替换了 FragmentStatePagerAdapter
。
假设offscreenPageLimit = 1
,ViewPager2
将有 3fragments
和 2 fragments
由RecylerView Preloading Strategies 预加载/缓存所以,总共会有 5 fragments
已加载。
为了禁用预加载和缓存,我执行了:
private void disableCacheOfViewPager()
try
// Disable Preloading
((RecyclerView) binding.pager.getChildAt(0)).getLayoutManager().setItemPrefetchEnabled(false);
// Disable Cache
((RecyclerView) binding.pager.getChildAt(0)).setItemViewCacheSize(0);
catch (NullPointerException e)
Log.i(TAG, "disableCacheOfViewPager: " + e.getMessage());
滚动之前的日志
//1st
onStart: 0
onResume: 0
onStart: 1
//2nd
onStart: 2
onPause: 0
onResume: 1
//3rd
onStart: 3
onPause: 1
onResume: 2
//4th
onStart: 4
onPause: 2
onResume: 3
//5th
onStart: 5
onStop: 0
onDestroyView: 0
onDestroy: 0
onDetach: 0
onPause: 3
onResume: 4
之后滚动日志
//1st
onStart: 0
onResume: 0
onStart: 1
//2nd
onStart: 2
onPause: 0
onResume: 1
//3rd
onStart: 3
onStop: 0
onDestroyView: 0
onDestroy: 0
onDetach: 0
onPause: 1
onResume: 2
【讨论】:
【参考方案2】:我有同样的问题,这是谷歌页面中列出的错误。我不确定解决方案,但一种方法是忘记一起使用ViewPager2
,然后返回:ViewPager & FragmentStatePagerAdapter
。似乎在旧实现中工作正常。
https://issuetracker.google.com/issues/154541095
【讨论】:
以上是关于使用 ViewPager2 和 FragmentStateAdapter 的片段生命周期行为的主要内容,如果未能解决你的问题,请参考以下文章
带有片段和 Jetpack 导航的 Viewpager2:恢复片段而不是重新创建它们