I'm creating a RecyclerView
with header where the header collapses as you scroll up the RecyclerView
. I can achieve this very closely with the layout below, with a transparent AppBarLayout
, and MyCoolView
which is the header. The parallax effect works great.
However, if the header is still visible and I fling the RecyclerView
, the RV scrolls slowly to the top and some of the items are under the Toolbar until the RV reaches the top of the view. I've been playing around with the scrollFlags
but haven't achieved a desirable result. Any suggestions on how to improve the fling experience so the items don't get clipped?
View the video and watch when its flinged --- https://www.dropbox.com/s/jppd6m7zo41k23z/20160609_151309.mp4?dl=0
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout
android:background="#00000000">
<android.support.design.widget.CollapsingToolbarLayout
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<com.android.myapp.MyCoolView
app:layout_collapseMode="parallax"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView/>
</android.support.design.widget.CoordinatorLayout>
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:
offset != 0
, but rather for offset == appBarLayout.getTotalScrollRange()
. I think.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With