I want my RecyclerView to not recycle some items
Use this:
recyclerView.getRecycledViewPool().setMaxRecycledViews(TYPE_CAROUSEL, 0);
This will not recycle any view of viewType TYPE_CAROUSEL
but if the item count of this type is very high, then it will reduce your performance significantly, maybe even cause OOMEs
EDIT
After reading MML13's answer, I think it might work for you. You are worried about items of your carousel being reinflated when that view is rebinded in outer RecyclerView. If all those carousel's are of same type, i.e., they all use same adapter, you can keep the adapter inside outer RecyclerView's ViewHolder, and just swap out data and call notifyDataSetChanged()
or notifyItemRangeChanged(...)
on this adapter when it's rebinded. This will recycle all carousel views and all views inside those carousels.
How to make RecyclerView stops recycling defined positions?
In your getItemViewType(int position)
method of adapter, assign unique values for each video, so it will always return same ViewHolder for same video as you wish.
- return unique positive number as type for each video type (here i used the adapter position as unique key)
- return negative numbers for any non-video items. (nothing special here, just to avoid conflicts with video items, we use negative numbers for non-video items)
I hope you get the idea. cheers :)
@Override
public int getItemViewType(int position) {
// Just as an example, return 0 or 2 depending on position
// Note that unlike in ListView adapters, types don't have to be contiguous
if(dataList.get(position).isVideo()){
return position;
}else{
return -1;//indicates general type, if you have more types other than video, you can use -1,-2,-3 and so on.
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case -1: View view1 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.general_item, parent, false);
return new GeneralViewHolder(view1);
default:View view2 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_item, parent, false);
return new VideoViewHolder(view2);
}
}
Avoid recycling of the items in the Recyclerview
Have you considered using ScrollView instead? You could include the different layout types you want to use inside the ScrollView, and there you would not get recycling behavior.
If that is not good enough, than I would sudgest to stick with recycler view, and not worry about views getting recycled, because it is not much of a big deal.
But if you are still convinced that you need a recycler view without the recycling behavior, you could try viewHolder.setIsRecyclable(false);
on every viewholder instantiation, that way they won't get recycled.
Android RecyclerView doesn't recycle items
Since your inner RV
's height is set to wrap_content
there is no way to enable recycling for that case. When its horizontal, recycling is working because it's width
is match_parent
and screen width is fixed. Recycling works only when there is defined height!
However, as i said there is room for optimization:
Right now, you are creating adapter for inner RV
inside parent RV's onBindViewHolder()
method, thus forcing inner RV
to inflate ViewHolders
every time parent RV
decides to reuse it's previous ViewHolders
via rebinding new values.
You can create adapters for inner RV
inside onCreateVoewHolder()
of parent RV
and submit new list to inner adapter ( subsequently calling notifyDatasetChanged()
) inside OnBindViewHolder()
.
The above approach should certainly improve performance, at least on subsequent scrolling: recycling will work on parent RV
scroll, meaning inner RV
will retain its ViewHolders
and reuse them to some degree.
Unfortunately, i don't have time to post snippet precisely for your scenario but you can have a look at my another answer:
Show values of same key in one TextView in Recyclerview
Android RecyclerView prevent recycling all items
The problem is that you should swap items in ListAdapter.mDiffer
which holds the current showing list. So, globalItemList
in your code is unused. Replace onRowMoved
of your adapter with the following one:
@Override
public void onRowMoved(int fromPosition, int toPosition) {
ArrayList<Shoppinglist> list = new ArrayList(getCurrentList());
Collections.swap(list, fromPosition, toPosition);
submitList(list);
}
Don't recycle specific view type in RecyclerView
use recyclerView.getRecycledViewPool().setMaxRecycledViews(YOUR_VIEW_TYPE, 0);
This will disable recycling of the specified view type
Prevent the adapter from recycling views on scroll ( Edit do not ever do this.)
Prevent the adapter from recycling views on scroll
Just don't use the convertView
param passed to getView()
and always return a freshly generated View
.
However, this is a bad solution in terms of performance. Instead, your goal should not be to prevent recycling but to recycle correcltly: Your getView()
should reset the convertView
to it's pristine state.
So, if there's a change that some of your Button
's properties are changed from their non-default values, reset them back to defaults in getView()
.
Related Topics
Android, How to Create Option Menu
Image Size for All Screen Devices
Getting Permission Denial Exception
Android Listview Row Delete Animation
How to Kill Sub Activities and Bring Activity to Top of Stack
Save Data and Change Orientation
Android Opengl Texture Compression
How to Use the Android Keystore to Securely Store Arbitrary Strings
Determine When a Viewpager Changes Pages
Play Sound Using Soundpool Example
How to Write a Custom Filter for Listview with Arrayadapter
Continually Running Background Service
Suppress/Block Broadcastreceiver in Another App
Android Studio 3.0 Manifest Error: Unknown Element <Action> Found
How to Disable Facebook Single Sign on for Android - Facebook-Android-Sdk