Understanding Recyclerview Sethasfixedsize

Understanding RecyclerView setHasFixedSize

A very simplified version of RecyclerView has:

void onItemsInsertedOrRemoved() {
if (hasFixedSize) layoutChildren();
else requestLayout();
}

This link describes why calling requestLayout might be expensive. Basically whenever items are inserted, moved or removed the size (width and height) of RecyclerView might change and in turn the size of any other view in view hierarchy might change. This is particularly troublesome if items are added or removed frequently.

Avoid unnecessary layout passes by setting setHasFixedSize to true when changing the contents of the adapter does not change it's height or the width.


Update: The JavaDoc has been updated to better describe what the method actually does.

RecyclerView can perform several optimizations if it can know in
advance that RecyclerView's size is not affected by the adapter
contents. RecyclerView can still change its size based on other
factors (e.g. its parent's size) but this size calculation cannot
depend on the size of its children or contents of its adapter (except
the number of items in the adapter).

If your use of RecyclerView
falls into this category, set this to {@code true}. It will allow
RecyclerView to avoid invalidating the whole layout when its adapter
contents change.

@param hasFixedSize true if adapter changes cannot affect the size of
the RecyclerView.

When do we use the recyclerView.setHasFixedSize?

It's interesting for the RecyclerView to know if its size (width and height dimensions) depends on the adapter content to avoid expensive layout operations. If the RecyclerView knows in advance that its size doesn't depend on the adapter content, then it will skip checking if its size should change every time an item is added or removed from the adapter. This is especially important because inserting an deleting elements can happen very often.

If the size of the RecyclerView (the RecyclerView itself)...

...doesn't depend on the adapter content:

mRecyclerView.setHasFixedSize(true);

...depends on the adapter content:

mRecyclerView.setHasFixedSize(false);

If you check the RecyclerView class you'll see it in more details because as of right now mHasFixedSize isn't used in that many places in that class.

Setting it as true doesn't mean that the RecyclerView size is fixed, just means it won't change because of change in the adapter content. For example the RecyclerView size can change because of a size change on its parent.

App doesn't display items on RecyclerView

You need to add a layoutManager to your recycler view:

    public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_articles, container, false);
recyclerView = root.findViewById(R.id.recyclerView);
NewsAdapter adapter = new NewsAdapter(myListData);
recyclerView.setHasFixedSize(true);
// Add this line
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()))
recyclerView.setAdapter(adapter);

return root;
}

Reusing the RecyclerView adapter so as to avoid unnecessary API call

Following the idea that it's beacuse of creating a new instance of Pager each time calling the fetchCards method. Here's an example for reusing the Pagers:

private val pagersMap = hashMapOf<String, Pager<String, UIModel>>()

fun fetchCards(orgId: String): Flow<PagingData<UIModel>> {
val pager: Pager<String, UIModel> = pagersMap[orgId] ?: createPager(orgId)
return pager.flow
}

private fun createPager(orgId: String): Pager<String, UIModel> {
val pager = Pager(
config = PagingConfig(
pageSize = 5,
enablePlaceholders = false,
initialLoadSize = 5
),
pagingSourceFactory = {
CardsPagingDataSource(orgId)
}
)
pagersMap[orgId] = pager
return pager
}

But you'd have to test it with your data types etc.

Remember to use the same instance of ViewModel in both Fragments. I didn't see how you instantiate the ViewModel but you can do it by scoping it to either an Activity or parent Fargmenet (depends on your app structure) - more details here.

If you can't do it, maybe you should create some Repository and take the Pagers from there.



Related Topics



Leave a reply



Submit