If this is still relevant, I think I managed to achieve the desired behavior.
First of all, to enable / disable scrolling, we need to implement a custom LinearLayoutManager (thanks to this post ):
public class CustomLayoutManager extends LinearLayoutManager { private boolean isScrollEnabled = true; public CustomLayoutManager(Context context) { super(context); } public void setScrollEnabled(boolean flag) { this.isScrollEnabled = flag; } @Override public boolean canScrollVertically() { return isScrollEnabled && super.canScrollVertically(); } }
and set it to RecyclerView :
layoutManager = new CustomLayoutManager(this); recyclerView.setLayoutManager(layoutManager);
Then we need to determine when to enable and disable scrolling. I did this using AppBarLayout.OnOffsetChangedListener :
appBarLayout = mainView.findViewById(R.id.app_bar_layout); appBarLayout .addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { // verticalOffset == 0 means that the AppBarLayout is expanded if (verticalOffset == 0) { // here we check that the last item of the RecyclerView is visible if (viewIsVisible(layoutManager.findViewByPosition(layoutManager.getItemCount() - 1))) { layoutManager.setScrollEnabled(false); } else { layoutManager.setScrollEnabled(true); } } } });
And here is a view visibility test method:
private boolean viewIsVisible(View view) { Rect scrollBounds = new Rect(); list.getHitRect(scrollBounds); return view != null && view.getLocalVisibleRect(scrollBounds); }
Kirill Simonov
source share