I have a ViewPager
that utilizes a RecyclerView
for each page and shares ViewItem
rows across pages. Accordingly I share a single RecyclerViewPool
between them. However, the ViewPager
loads each RecyclerView
whether or not it is the page on screen. Is there a way to indicate to the RecyclerView that all of its items are offscreen and force its views to be returned to the Recycler
?
My sense is that subclassing LinearLayoutManager
and overriding its onLayoutChildren
method is the way to go, but I don't have much experience with LayoutManager
and would like some guidance.
So here is a subclass of LinearLayoutManager
that operates the way I described:
public class PageVisibleLinearLayoutManager extends LinearLayoutManager {
public PageVisibleLinearLayoutManager(Context context) {
super(context);
}
public PageVisibleLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public PageVisibleLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private boolean pageVisible = true;
void setPageVisible(boolean pageVisible) {
boolean change = (this.pageVisible != pageVisible);
this.pageVisible = pageVisible;
if(change) requestLayout();
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if(pageVisible) {
super.onLayoutChildren(recycler, state);
} else {
removeAndRecycleAllViews(recycler);
}
}
}
It works nicely and gives up its views if requested. As dsh mentioned, it is important to mark adjacent pages as being on screen (and I really don't know why setOffscreenPageLimit
doesn't limit the number of pages loaded as expected). My previous solution was to use ViewStub
and inflate a page only when it was on screen or adjacent. The layout manager method is slightly faster upon initial turning to an unloaded page, but ViewStub
has the advantage of pages staying in memory once loaded (making subsequent scrolling more smooth), so I decided to stick with that.
Thank you all. Next question...