RecyclerView ambiguos setVisibility函数,单击一个视图会影响多个视图

555*_*597 9 android listview textview android-imageview android-recyclerview

这是我想要运行的项目.这是我在RecyclerView.Adapter类中的onBindViewHolder的代码

@Override
    public void onBindViewHolder(ViewHolder holder, final int position) {

        TextView title = (TextView) holder.view.findViewById(R.id.title);
        final TextView desc = (TextView) holder.view.findViewById(R.id.desc);
        final ImageView imageView = (ImageView) holder.view.findViewById(R.id.imageView);

        title.setText(pojos.get(position).getTitle());
        desc.setText(pojos.get(position).getDesc());

        imageView.setImageResource(pojos.get(position).getImage());

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                desc.setText("clicked");
                desc.setBackgroundColor(Color.BLUE);
                imageView.setImageResource(R.drawable.heart_red);
            }
        });

    }
Run Code Online (Sandbox Code Playgroud)

列表加载正常,问题发生在调用imageView的onclicklistener时.

desc.setText("clicked");
Run Code Online (Sandbox Code Playgroud)

上面的行在单击它的列表项中进行更改.但

 desc.setBackgroundColor(Color.BLUE);
Run Code Online (Sandbox Code Playgroud)

执行此行时,更改将反映在列表中的多个项目中.出了什么问题?在下面显示的图片中,我点击了第0项,文本变为"点击"并设置了颜色.但是当我向下滚动时,项目12也受到了我对项目0的点击的影响.仅反映了背景颜色变化,而不是文本更改.我怎么阻止这个?

在此输入图像描述

在此输入图像描述

我一直试图解决这个问题很长时间,请下载项目并尝试执行代码以了解我的意思,如果我的问题不明确.

Moo*_*oom 12

发生这种情况是因为视图被回收并重复使用.

因此,当视图被回收时,如果不再次更改它,它将保留"旧"视图的属性.因此,当您向下滚动到数字12时,用于保存数字1的视图将被回收(因为它不再在屏幕上显示),并用于创建数字12.这就是为什么蓝色在数字上的原因12.

例如,当单击该项目时,您需要将"单击"值保存到POJO对象中.然后,在绘制项目时,检查该值并根据该值设置正确的图像/背景颜色.

我已经在下面的代码中完成了这个,所以它应该让你大致了解该怎么做:

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    TextView title = (TextView) holder.view.findViewById(R.id.title);
    final TextView desc = (TextView) holder.view.findViewById(R.id.desc);
    final ImageView imageView = (ImageView) holder.view.findViewById(R.id.imageView);

    final MyPojo pojo = pojos.get(position);

    title.setText(pojo.getTitle());
    if(!pojo.clicked) {
        desc.setText(pojo.getDesc());
        imageView.setImageResource(pojo.getImage());
        desc.setBackgroundColor(Color.argb(0,0,0,0));
    } else {
        desc.setText("clicked");
        desc.setBackgroundColor(Color.BLUE);
        imageView.setImageResource(R.drawable.heart_red);
    }

    imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            pojo.clicked = true;
            desc.setText("clicked");
            desc.setBackgroundColor(Color.BLUE);
            imageView.setImageResource(R.drawable.heart_red);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

我已经为MyPojo类添加了一个"clicked"布尔值.

public class MyPojo {

    String title;
    String desc;
    int image;
    boolean clicked;
 }
Run Code Online (Sandbox Code Playgroud)


Dal*_*iya 12

只需在getItemCount方法之后在适配器类中添加一个方法

@Override
    public int getItemViewType(int position) {
        return position;
    }
Run Code Online (Sandbox Code Playgroud)

它会解决问题

  • 这实际上也打破了使用RecyclerView的全部要点.这会禁用所有视图重用.您基本上告诉RecyclerView列表中的每个项目都应该有自己的视图单元,永远不能回收.因此,如果您将图像加载到这些RecyclerView单元格中,您的内存使用量将会通过. (3认同)