Reputation:
Hi everyone I'm stuck in this and need help :
Each item has a CheckBox
and I set setOnLongClickListener
for root element of my items in RecyclerView
like this :
holder.faviorateVideoItemRelative.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View arg0) {
if (chk_visible)
{
return true ;
}
holder.chk_faviorateVideo.setChecked(!holder.chk_faviorateVideo.isChecked());
chk_visible = true ;
checkedItemsCNT = 1 ;
deleteListVideoCourses.add(data.get(holder.getAdapterPosition())) ;
notifyDataSetChanged() ;
return true ;
}
});
If I scroll down , when I make a long click on one of items , the CheckBox
of wrong item get checked !
Upvotes: 8
Views: 4285
Reputation: 21
After using the above mentioned solutions,
The following solutions worked like a charm for me.
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
using holder.setIsRecyclable(false)
removes the desired selection as well when you come back to it after the whole scrolling process.
Upvotes: 0
Reputation:
It because as you use RecycleView
it reuse your view every time when you scroll. RecycleView
reuse your resource like this
So when you scroll it's showing the wrong state of your view
If you write any logic for check-in onBindViewHolder
then you have to use both part for true and false
if(yourCondition){
//code if condition is true
}else {
//code if condition is false
}
Simply you can solve it just using one statement to stop your RecycleView
to reuse your view state like this
@Override
public void onBindViewHolder(ReqNotificationAdapter.MyViewHolder holder, int position) {
holder.setIsRecyclable(false);
//.................your other code
}
I use it to solve my problem.. hope it will solve yours if you don't have a problem stop Recycling with your purpose.
Upvotes: 19
Reputation: 17131
Solution 1:
You can override two method getItemId, getItemViewType.
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
Like this:
public class EasyAdapter extends RecyclerView.Adapter<EasyAdapter.ViewHolder>{
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
}
Solution 2: Set setIsRecyclable false.
EasyAdapter easyAdapter=new EasyAdapter();
easyAdapter.setIsRecyclable(false);
Upvotes: 1
Reputation: 857
When you initialize your OnLongClickListener, it is reused in views when they are no longer visible because they are cached. To solve the worry, create a new class to explicitly link an object to a listener and not just the view. For example :
private class BufferVideoLongClickListener implements View.OnLongClickListener {
private VideoObject video; // And other stuff like checked, etc
BufferVideoLongClickListener(VideoObject video, ...) {
this.video = video;
...
}
@Override
public void onLongClick(View view) {
// Do your check and other things
if(checked)
...
}
}
And in your onBindViewHolder :
holder.faviorateVideoItemRelative.setOnLongClickListener(new BufferVideoLongClickListener(video, ...));
Upvotes: 0
Reputation: 13865
Could be an issue in your bind rather than setting of the value.
A common mistakes is not un-checking the view in the bind.
Make sure where you are setting checked, you have an else statement and set it to unchecked.
RecyclerView and Listview reuse views as they scroll, which includes any previously checked boxes. So it is important to un-check them if appropriate.
public void bindView(View view, ..... //varies on implementation. rough idea.
{
CheckBox mycheckbox = (CheckBox)view.findViewById(R.id.myidofcheckbox);
int pos = view.getPosition();
if(pos == 1) //example
mycheckbox.setChecked(true);
else
mycheckbox.setChecked(false);
Upvotes: 1
Reputation: 2577
Yes it happens with ListView and RecyclerView
Try this code,
holder.faviorateVideoItemRelative.setTag(position);
holder.faviorateVideoItemRelative.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View arg0) {
int tempPos = (int)holder.faviorateVideoItemRelative.getTag();
if (chk_visible)
{
return true ;
}
if(!holder.chk_faviorateVideo.isChecked())
{
holder.chk_faviorateVideo.setChecked(true);
}
else
{
holder.chk_faviorateVideo.setChecked(false);
}
holder.chk_faviorateVideo.setChecked(!holder.chk_faviorateVideo.isChecked());
chk_visible = true ;
checkedItemsCNT = 1 ;
deleteListVideoCourses.add(data.get(tempPos)) ;
notifyDataSetChanged() ;
return true ;
}
});
Hope it will help you.
Upvotes: 0