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_height
和layout_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:
我有一个水平的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_height
和layout_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: