Loading large number of items in recycler view
you may achieve this by using AndroidX Room & Paging
- cache your data from network to local Room Database
- using Paging to load your data from Room Database
Sort answer:
LinearLayoutManager(context).apply { isAutoMeasureEnabled = false }
// or in Java
layoutManager.setAutoMeasureEnabled(false)
UPDATE 2020.08.14
Deprecated RecyclerView.LayoutManager#setAutoMeasureEnabled
This method was deprecated in API level 27.1.0. Implementors of LayoutManager should define whether or not it uses AutoMeasure by overriding isAutoMeasureEnabled()
From the doc of RecyclerView.LayoutManager#setAutoMeasureEnabled() we know :
This method is usually called by the LayoutManager with value {@code true} if it wants to support WRAP_CONTENT
It works by calling {@link LayoutManager#onLayoutChildren(Recycler, State)} during an {@link RecyclerView#onMeasure(int, int)} call, then calculating desired dimensions based on children's positions.
If we set mAutoMeasure = true
, it will call LayoutManager#onLayoutChildren(Recycler, State)
during an RecyclerView#onMeasure(int, int)
call. Every child view's onMeasure()
method will be called, this cost too much time.
Let's look at LinearLayoutManager's constructor
public LinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
setOrientation(orientation);
setReverseLayout(reverseLayout);
setAutoMeasureEnabled(true);
}
So, after we set mAutoMeasure = false
, everything will be ok.
Do you load the data all at once? RecycleView should not have problem, I think if you have too much data the processing itself can take too much time. You should load the data in chunks and check the scroll state of the user and load the next batch etc. kinda how Instagram or Facebook does it.
Solved the problem by removing the NestedScrollView over the recyclerview. The nestedscrollview was not allowing the recyclerview.addOnScrollListener() to be called because of which I was getting a lag on loading more items. Here is how i implemented the loadOnScroll for RecyclerView-
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!recyclerView.canScrollVertically(1))
onScrolledToBottom();
}
});
private void onScrolledToBottom() {
if (songMainList.size() < songAllList.size()) {
int x, y;
if ((songAllList.size() - songMainList.size()) >= 50) {
x = songMainList.size();
y = x + 50;
} else {
x = songMainList.size();
y = x + songAllList.size() - songMainList.size();
}
for (int i = x; i < y; i++) {
songMainList.add(songAllList.get(i));
}
songsAdapter.notifyDataSetChanged();
}
}