【Android】RecyclerView复用CheckBox的异常状态

三三要成为安卓糕手

一:问题场景引入

问题描述:勾选了2、4两个item的check框,向下滑动,新的item上来莫名其妙也被勾选上了!

分析向上滑动,Holder被划出,Holder会被复用,就造成了下面的item被打了勾的Holder利用,就造成了上述场景发生的bug问题

需求:一句话就是跟RecyclerView中ViewHolder的复用有关系

打勾的check勾选框所在的Holder被回收复用后被新的item利用,根本原因就是check是跟Holder捆绑在一起的,

打个比方一个被做了标记的杯子,装过咖啡,又装奶茶;可以说咖啡和奶茶都被一个做过标记的杯子装过

二:解决方案

核心:控制勾选状态,在绑定Holder中Check框的状态取决于Article中的check属性;check属性由监听器控制,就是这样;

非常言简意赅

三:需要修改增添的代码

1:新增check属性

Article类中新增check属性,并添加get和set方法

java 复制代码
import android.widget.CheckBox;

public class Article {
    private boolean check;

    public boolean isCheck() {
        return check;
    }

    public void setCheck(boolean check) {
        this.check = check;
    }
}

2:xml布局加Check框

给MyViewHolder类对应的xml布局加上一个Check框

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="12dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <CheckBox
            android:id="@+id/check_box"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="勾选"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_author" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

3:勾选监听器控制check属性

java 复制代码
    /**
     *  有一条item就调用一次这个方法
     */
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Log.i(TAG, "onBindViewHolder: position" + position);

        Article article = articles.get(position);
        holder.ivPicture.setImageResource(article.getPicture());
        holder.tvTitle.setText(article.getTitle());
        holder.tvAuthor.setText(article.getAuthor());
        holder.checkBox.setChecked(article.isCheck());
    }
java 复制代码
public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            ivPicture = itemView.findViewById(R.id.iv_picture);
            tvTitle = itemView.findViewById(R.id.tv_title);
            tvAuthor = itemView.findViewById(R.id.tv_author);
            checkBox = itemView.findViewById(R.id.check_box);

            checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    Article article = articles.get(getLayoutPosition());
                    article.setCheck(isChecked);
                }
            });
        }
相关推荐
沉木渡香1 小时前
VSCode中Java开发环境配置的三个层级(Windows版)1-3
java·windows·vscode
程序员小白条1 小时前
度小满运维开发一面
java·运维·python·职场和发展·运维开发
Leo655356 小时前
JDK8 的排序、分组求和,转换为Map
java·开发语言
Filotimo_6 小时前
2.CSS3.(2).html
前端·css
yinuo7 小时前
uniapp微信小程序华为鸿蒙定时器熄屏停止
前端
gnip8 小时前
vite中自动根据约定目录生成路由配置
前端·javascript
书源丶8 小时前
二十八、API之《System 类》——与系统交互的“桥梁”
java·交互
Pluchon8 小时前
硅基计划4.0 算法 字符串
java·数据结构·学习·算法
折翅鵬9 小时前
Android 程序员如何系统学习 MQTT
android·学习
野生技术架构师9 小时前
1000 道 Java 架构师岗面试题
java·开发语言