How To Make Recyclerview Stops Recycling Defined Positions?
Solution 1:
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 :)
@OverridepublicintgetItemViewType(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 contiguousif(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.
}
}
@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case -1: Viewview1= LayoutInflater.from(parent.getContext())
.inflate(R.layout.general_item, parent, false);
returnnewGeneralViewHolder(view1);
default:Viewview2= LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_item, parent, false);
returnnewVideoViewHolder(view2);
}
}
Solution 2:
Perform viewHolder.setIsRecyclable(false)
on the ViewHolder
you want not to be recycled.
From docs of ViewHolder#setIsRecyclable(boolean):
Informs the recycler whether this item can be recycled. Views which are not recyclable will not be reused for other items until setIsRecyclable() is later set to true.
This will cause only one ViewHolder
to be created.
publicclassMyAdapterextendsRecyclerView.Adapter<RecyclerView.ViewHolder> {
...
@OverridepublicvoidonViewAttachedToWindow(final RecyclerView.ViewHolder holder) {
if (holder instanceof VideoViewHolder) {
holder.setIsRecyclable(false);
}
super.onViewAttachedToWindow(holder);
}
@OverridepublicvoidonViewDetachedFromWindow(final RecyclerView.ViewHolder holder) {
if (holder instanceof VideoViewHolder){
holder.setIsRecyclable(true);
}
super.onViewDetachedFromWindow(holder);
}
...
}
Solution 3:
RecyclerView uses one view multiple times, when it contains the list which is not displaying on the screen at a time(means a list contain large amount of items which is not displaying on screen at same time you need to scroll up and down). When user scroll the list the offscreen items are reused to display the remaining list items which is called recycling.
To Stop recycling the items call this method in your onBindViewHolder method:
viewHolder.setIsRecyclable(false);
This statement stop the recycling the views.
To Start recycling the items call this method in your onBindViewHolder method:
viewHolder.setIsRecyclable(true);
I hope this will solve your problem. Thanks
Solution 4:
Your problem comes from the viewholder itself. Viewholders keep reference to views, while the adapter don't. The adapter keeps the data collection only. So, add a field to the viewholder to keep a reference of the data element you used to populate the view in the viewholder. In other words:
publicclassSomeViewHolderextendsRecyclerView.ViewHolder{
private View view;
private Data data;
public SomeViewHolder(View itemView) {
super(itemView);
view = itemView;
}
public void bindData(Data data){
view.setData(data);
this.data = data;
}
public void setData(Data data){
this.data = data;
}
public Data getData(){
returndata;
}
public View getView(){
return view;
}
}
Now, the viewholder know which element of the adapter is using. Therefore, when overriding the binding method in the adapter, you can check if the holder has already bonded with some data, and, if the data contains video, you can avoid the binding and forcefully set an already loaded view.
@Override
publicvoidonBindViewHolder(SomeViewHolder holder, int position) {
//videoViewData is a data field you have to put into the adapter.//videoView is a view field you have to put into the adapter.if(adapterData.get(position).equals(videoViewData)){
holder.setView(videoView);
holder.setData(adapterData.get(position));
}else{
holder.bindData(adapterData.get(position));
if(adapterData.get(position).isVideo()){
videoViewData = adapterData.get(position);
videoView = holder.getView();
}
}
}
Finally, you'll have to override the onViewRecycled method in the adapter, so, when a view containing a video gets recycled, you can get the view and put it somewhere else.
publicvoidonViewRecycled(SomeViewHolder holder){
if(holder.getData().isVideo()){
videoViewData = holder.getData().
videoView = holder.getView();
videoView.pauseVideo();
}
}
keep in mind, this can cause some serious leaks if you don't manage the stored view. Also, you have to define methods for telling when your data is video, and a properly defined equals method.
Solution 5:
Best way to handle item not to recycle in recyclerview this answer will resolve your problem.
Post a Comment for "How To Make Recyclerview Stops Recycling Defined Positions?"