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

来源:互联网 发布:淘宝子账号客服权重值 编辑:程序博客网 时间:2024/05/16 17:02

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;

@Overrideprotected 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、以上 就可以实现了 , 希望可以帮助到大家 , 让大家少走一点点弯路,最后贴上 源码下载地址

阅读全文
0 0
原创粉丝点击