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