Prevent RecyclerView from scrolling under AppBarLayout before AppBarLayout is collapsed
Possible solution (untested). Add an OnOffsetChangedListener
to your AppBarLayout
, and keep note of the offset value. First, declare this field:
private boolean shouldScroll = false;
Then, onCreate:
AppBarLayout appbar = findViewById(...);
appbar.addOnOffsetChangedListener(new OnOffsetChangedListener() {
@Override
void onOffsetChanged(AppBarLayout appbar, int offset) {
// Allow recycler scrolling only if we started collapsing.
this.shouldScroll = offset != 0;
}
});
Now, add a scroll listener to your RecyclerView. Whenever it tries to scroll, revert the scroll if the AppBarLayout is still expanded:
RecyclerView recycler = findViewById(...);
recycler.addOnScrollListener(new OnScrollListener() {
@Override
void onScrolled(RecyclerView recycler, int dx, int dy) {
// If AppBar is fully expanded, revert the scroll.
if (!shouldScroll) {
recycler.scrollTo(0,0);
}
}
});
This might need some tweaking though. I see two issues:
- Possible stack overflow if scrollTo() calls onScrolled() back. Can be solved with a boolean or by removing/adding the scroll listener
- Possibly you want to prevent scrolling not only when AppBarLayout is fully expanded, but more generally when AppBarLayout is not collapsed. This means you don’t have to check for
offset != 0
, but rather foroffset == appBarLayout.getTotalScrollRange()
. I think.