RecyclerView 无限滚动在 ViewPager2 中不起作用

RecyclerView infinite scroll not working inside ViewPager2

我有一个水平的ViewPager2。在视图寻呼机的第二张幻灯片上,我有一个 RecyclerView 实现了无限滚动。我使用 EndlessRecyclerViewScrollListener 来实现无限滚动。

但是,当向下滚动 RecyclerView 时,它不会触发无限滚动。永远不会调用无限滚动的第 2 页,只调用第 1 页。

这是我的 class 和 ViewPager2:

public class BaseBottomNavigationViewActivity extends BaseActivity implements BottomNavigationView.OnNavigationItemSelectedListener {

    // The number of pages in the bottom navigation view
    private static final int NUM_PAGES = 5;

    // The view pager
    private ViewPager2 viewPager;

    // The pager adapter
    private FragmentStateAdapter pagerAdapter;

    // The bottom navigation view
    private BottomNavigationView bottomNavigationView;

    private NewPostBottomSheetDialogFragment newPostModalDialog;

    private RelativeLayout newPostButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        viewPager = findViewById(R.id.view_pager);
        bottomNavigationView = findViewById(R.id.bottom_navigation_view);

        // The number of screens to keep in memory
        viewPager.setOffscreenPageLimit(5);

        // Disable swiping in the view pager
        viewPager.setUserInputEnabled(false);

        // Set the pager adapter
        pagerAdapter = new BottomNavigationViewPagerAdapter(this);
        viewPager.setAdapter(pagerAdapter);

        // Register the item selected listener
        bottomNavigationView.setOnNavigationItemSelectedListener(this);

        // Set default selection (home)
        bottomNavigationView.setSelectedItemId(R.id.action_first);
    }

    @Override
    protected int getLayoutResource() {
        return R.layout.activity_base_bottom_navigation_view;
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_first:
                viewPager.setCurrentItem(0, false);
                break;
            case R.id.action_second:
                viewPager.setCurrentItem(1, false);
                break;
            case R.id.action_third:
                return false;
            case R.id.action_fourth:
                viewPager.setCurrentItem(3, false);
                break;
            case R.id.action_fifth:
                viewPager.setCurrentItem(4, false);
                break;
            default:
                break;
        }

        return true;
    }

    private static class BottomNavigationViewPagerAdapter extends FragmentStateAdapter {
        public BottomNavigationViewPagerAdapter(FragmentActivity fa) {
            super(fa);
        }

        @Override
        public Fragment createFragment(int position) {
            switch (position) {
                case 0:
                    return new FirstPageFragment();
                case 1:
                    return new SecondPageFragment();
                case 2:
                    return new ThirdPageFragment();
                case 3:
                    return new FourthPageFragment();
                case 4:
                    return new FifthPageFragment();
            }

            return null;
        }

        @Override
        public int getItemCount() {
            return NUM_PAGES;
        }
    }

}

这是 ViewPager2 中第二页的 class:

public class SecondPageFragment extends Fragment {

    private MyAdapter myAdapter;

    private LinearLayoutManager layoutManager;

    private RecyclerView recyclerView;

    private EndlessRecyclerViewScrollListener scrollListener;

    private List<Object> objects = new ArrayList<>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_page_two, parent, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        recyclerView = view.findViewById(R.id.recycler_view);

        layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);

        myAdapter = new MyAdapter(getContext(), layoutManager, objects);
        recyclerView.setAdapter(myAdapter);

        scrollListener = new EndlessRecyclerViewScrollListener(layoutManager) {
            @Override
            public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                getData(page);
            }
        };
        recyclerView.addOnScrollListener(scrollListener);
    }

    private void getData(final int page) {
        // Here I call the API to fetch the data and add them to the objects list
    }
}

为什么在这种情况下滚动时不为 RecyclerView 调用第 2 页,我该如何解决?

谢谢!

您可能有兴趣检查您对 ViewPager2 的约束,因为它托管包含 RecyclerView 的片段 - 以及该特定片段的整个结构(在您的 XML 布局中)。

由于两者都是可滚动的,因此布局层次结构的layout_heightlayout_width极大地影响了recyclerView的事件何时被触发,其中一些可能永远不会到达事件监听器。

在从 ViewPager 迁移的官方文档中,有一个关于支持嵌套滚动的小说明 here

ViewPager2 does not natively support nested scroll views in cases where the scroll view has the same orientation as the ViewPager2 object that contains it. For example, scrolling would not work for a vertical scroll view inside a vertically-oriented ViewPager2 object.

假设您的 RecyclerView 未使用与 viewPager 相同的方向,您可以 运行 自己的片段并进行调试以确定 onLoadMore 是否真的被当不在 viewPager context/container.

中时触发

作为旁注,抽出时间阅读 Paging3 及以后的内容。

我最终通过使用不同的无限滚动 RecyclerView 解决了这个问题 class: