RecylerView配合ChekBox实现单选,解决了因为复用导致单选框混乱现象

1、大家经常遇到recylerView需要单选的情况吧,其实这个实现起来很简单,话不多说 先来看下效果。滚动过程中,界面复用时 均没有出现单选框混乱的情况
2、好吧 大家如果觉得效果还算可以的话,就继续往下看吧。
思路:
首先,recylerview的item里面 有一个 checkBox,在点击的时候 将checkBox 设置为true,并将上一次设置为true的checkBox设置为false,达到我们单选的需求。(好吧,其实 我也试过很多其他的方式方法,但是效果都不理想,尤其当复用上一次item的时候会出现单选框混乱的情况,最后 筛选出这个方法,经测试,效果不错)。
3、思路已经出来了 搞就完事了
首先主页面布局界面:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <TextView
        android:id="@+id/tv_dept_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="15dp"
        android:textSize="14sp" />

    <View
        android:id="@+id/space"
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_below="@id/tv_dept_name" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/space"
        android:layout_marginBottom="70dp" />

    <RelativeLayout
        android:id="@+id/bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:padding="10dp">

        <TextView
            android:id="@+id/btn_cancle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:paddingBottom="10dp"
            android:paddingLeft="30dp"
            android:paddingRight="30dp"
            android:paddingTop="10dp"
            android:text="取消"
            android:textSize="14sp" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="已选择"
                android:textSize="13sp" />

            <TextView
                android:id="@+id/name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="周杰伦"
                android:textSize="14sp" />
        </LinearLayout>

        <TextView
            android:id="@+id/btn_ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:paddingBottom="10dp"
            android:paddingLeft="30dp"
            android:paddingRight="30dp"
            android:paddingTop="10dp"
            android:text="确定"
            android:textSize="14sp" />
    </RelativeLayout>
</RelativeLayout>

啥也没有 很简单 就是一个 recylerView
完了 item的布局界面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#FFFFFF"
    android:padding="10dp">

    <ImageView
        android:id="@+id/cover"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignParentLeft="true"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/user_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="15dp"
        android:layout_toRightOf="@id/cover"
        android:textSize="15sp" />

    <CheckBox
        android:id="@+id/check_box"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true" />
</RelativeLayout>

如上面代码所示 里面 有一个 imageview 一个 textView 和一个checkBox,其中 我们主要关注的是checkBox的情况,`package rab.gosspell.com.myapplication;

/**
* author:lirui on 2017/12/20.
* todo//
* version:v1.0
*/

public class SelectPersonEntity {
String name;
boolean isCheck;
String icon;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public boolean isCheck() {
    return isCheck;
}

public void setCheck(boolean check) {
    isCheck = check;
}

public String getIcon() {
    return icon;
}

public void setIcon(String icon) {
    this.icon = icon;
}

public SelectPersonEntity(String name, boolean isCheck, String icon) {

    this.name = name;
    this.isCheck = isCheck;
    this.icon = icon;
}

}
`这是显示的实体类,其中,重要的 就是 这个 isCheck 这个 布尔类型的值,因为 我们需要 通过这个值来控制,checkBox是不是选中的状态,

好,准备工作已经做完了,接下来是 最核心的代码了 我这里 为了方便 将 adapter以内部类的形式写在了 Activity中,如果你的需求 不允许 或者 个人习惯不喜欢,可以将其独立出来。`package rab.gosspell.com.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
List list;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    RecyclerView recyclerView = findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
    list = new ArrayList<>();
    list.add(new SelectPersonEntity("周杰伦", false, ""));
    list.add(new SelectPersonEntity("林俊杰", false, ""));
    list.add(new SelectPersonEntity("啥精神可嘉", false, ""));
    list.add(new SelectPersonEntity("sad", false, ""));
    list.add(new SelectPersonEntity("周杰伦", false, ""));
    list.add(new SelectPersonEntity("林俊杰", false, ""));
    list.add(new SelectPersonEntity("啥精神可嘉", false, ""));
    list.add(new SelectPersonEntity("sad", false, ""));
    list.add(new SelectPersonEntity("周杰伦", false, ""));
    list.add(new SelectPersonEntity("林俊杰", false, ""));
    list.add(new SelectPersonEntity("啥精神可嘉", false, ""));
    list.add(new SelectPersonEntity("sad", false, ""));
    list.add(new SelectPersonEntity("周杰伦", false, ""));
    list.add(new SelectPersonEntity("林俊杰", false, ""));
    list.add(new SelectPersonEntity("啥精神可嘉", false, ""));
    list.add(new SelectPersonEntity("sad", false, ""));
    recyclerView.setAdapter(new MyAdapter());
}

class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    private int mSelectedPos = -1;

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_person, parent, false));
        return holder;
    }

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

        if (list.get(position).isCheck()) {
            holder.checkBox.setChecked(true);
        } else {
            holder.checkBox.setChecked(false);
        }
        holder.checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //如果是-1 就表明是第一进来的没有
                if (mSelectedPos != -1) {
                    list.get(mSelectedPos).setCheck(false);
                }
                mSelectedPos = position;
                list.get(position).setCheck(!list.get(position).isCheck());
                notifyDataSetChanged();
            }
        });
        holder.userName.setText(list.get(position).getName());
    }


    @Override
    public int getItemCount() {
        return list.size();
    }
}

}

class MyViewHolder extends RecyclerView.ViewHolder {
public CheckBox checkBox;
public TextView userName;
public ImageView userImg;

public MyViewHolder(View itemView) {
    super(itemView);
    checkBox = (CheckBox) itemView.findViewById(R.id.check_box);
    userName = (TextView) itemView.findViewById(R.id.user_name);
    userImg = (ImageView) itemView.findViewById(R.id.cover);
}

}
`
其中的 重点都在Adapter里面,重点关注
1、 if (list.get(position).isCheck()) {
holder.checkBox.setChecked(true);
} else {
holder.checkBox.setChecked(false);
}
这个应该很好理解吧 , 我们判断了 if 一定要 写else里面的操作,不然会出现混乱情况
2、 holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//如果是-1 就表明是第一进来的没有
if (mSelectedPos != -1) {
list.get(mSelectedPos).setCheck(false);
}
mSelectedPos = position;
list.get(position).setCheck(!list.get(position).isCheck());
notifyDataSetChanged();
}
});
通过 设置监听事件(不要使用 addOnSelectChangeListen),首先判断,我们记录的上个值是不是-1,排除第一次进入的情形(因为这里没有做默认选中操作),然后,点击 某一个checkBox的时候,就把上一次记录的 checkBox设置为 false,把这次点击的 设置为false,(记住 要设置 list里面属性的值,不能单纯的设置界面的变化),然后调用notifyDataSetChanged方法,即可实现。
3、以上 就可以实现了 , 希望可以帮助到大家 , 让大家少走一点点弯路,最后贴上 源码下载地址

猜你喜欢

转载自blog.csdn.net/l13020227067/article/details/78851611