使用ViewPager2和FragmentStateAdapter时的碎片生命周期行为

5
我正在使用ViewPager2FragmentStateAdapter来显示5个fragments。每个fragment都有一个ExoPlayer实例。我保持着ViewPager2.setOffscreenPageLimit(1),它对于加载fragments很有效。然而,当我向下滚动ViewPager2pos4时,pos2pos1应该调用onStop()onDestroyView()onDestroy()。但是这并没有发生。

除非我按onBackPress(), 否则这些方法都不会执行。在实现中还有什么我遗漏的地方吗?

我想在onDestroyView()上执行exoPlayer.release()以释放应用程序的内存。

以下是代码

Activity

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();
    }

}

Updated

This is also a similar question


你尝试在onDestroy中释放exo player实例而不是在onDestroyView中吗? - Parag Pawar
@ParagPawar 我删掉之前的评论以避免混淆。最终,我得到了一个令人满意的解决方案。请参考答案 :) - Rajat Sangrame
2个回答

4

我参考了这篇文章来解决问题。

VeiwPager2基于RecyclerView组件构建,而FragmentStateAdapter替代了FragmentStatePagerAdapter

假设offscreenPageLimit = 1ViewPager2将有3个片段和由RecylerView预加载策略预加载/缓存的2个片段。因此,总共会加载5个片段

为了禁用预加载和缓存,我执行了以下操作:

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

1
我遇到了同样的问题,这是谷歌页面上列出的一个错误。我不确定解决方案,但一个方法是放弃使用ViewPager2,转而使用ViewPager & FragmentStatePagerAdapter。在旧实现中似乎可以正常工作。

https://issuetracker.google.com/issues/154541095


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接