wrong item changes in recyclerview

孤人 提交于 2019-12-30 11:26:07

问题


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 !


回答1:


It because as you user RecycleView it reuse your view every time when you scroll. RecycleView reuse your resource like this

So when you scroll it's showing wrong state of your view

Solution

If you write any logic for check in onBindViewHolder then you have to user both part for true and false

if(yourCondition){
   //code if condition is true
}else {
   //code if condition is false
}

Other Solution

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 problem stop Recycling with your purpose.




回答2:


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);



回答3:


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.




回答4:


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, ...));



回答5:


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);


来源:https://stackoverflow.com/questions/45029681/wrong-item-changes-in-recyclerview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!