Android RecyclerView中实现ChecckBox单选的正确方式
2016-12-05 12:04
661 查看
以前使用recyclerView时,如果item中有单选框需要选中,一般的实现方式是创建一个boolean类型的ArrayList用来存储列表中每个item的checkBox是否选中,设置一个标志位mCurrentPosition来记录当前被选中的checkBox的item的position,然后在每次点击item时,设置ArrayList的list中mCurrentPosition(也就是上一次选中的item)的值为false,设置list中当前position的boolean为true,设置mCurrentPosition为当前position,然后再调用Adapter.notifyDatasetChanged()方法刷新recyclerView。
这种方式缺点一是需要创建一个ArrayList的列表数组,占内存。如果recyclerView的数据源数据量很大,那么就会造成更大的内存存储开销,浪费了手机上宝贵的内存资源。缺点二是调用了notifyDataSetChanged方法后会刷新当前recyclerView中所有可见的item,也就是会重新调用onBindViewHolder这个方法来重新刷新item,会造成图片闪烁,虽然只是刷新当前可见的item,数量不多,对性能来说影响不大,但我们还是要保持对性能优化的极致的追求,最好的做法就是只刷新当前2个item就可以了,下面介绍一下怎么正确实现recyclerView中的单选。
效果图:
主要是Adapter的实现:
Activity:
布局文件:
最重点的还是RecyclerView中的onBindViewHolder的三个参数的方法
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position,List payloads)
和notifyItemChanged的两个参数的方法
public final void notifyItemChanged(int position, Object payload)
接下来分析这两个方法的介绍 详情见下一章博客
http://blog.csdn.net/qq402164452/article/details/53464091
这种方式缺点一是需要创建一个ArrayList的列表数组,占内存。如果recyclerView的数据源数据量很大,那么就会造成更大的内存存储开销,浪费了手机上宝贵的内存资源。缺点二是调用了notifyDataSetChanged方法后会刷新当前recyclerView中所有可见的item,也就是会重新调用onBindViewHolder这个方法来重新刷新item,会造成图片闪烁,虽然只是刷新当前可见的item,数量不多,对性能来说影响不大,但我们还是要保持对性能优化的极致的追求,最好的做法就是只刷新当前2个item就可以了,下面介绍一下怎么正确实现recyclerView中的单选。
效果图:
主要是Adapter的实现:
public class ContactSelectAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<AVUser> mList;//数据源 private Context mContext;//context上下文 private LayoutInflater mInflater;//布局解析器 用来解析布局生成View的 private int mSelectedPos=-1;//保存当前选中的position 重点! //构造函数,传入context和与当前adapter绑定的recyclerView public ContactSelectAdapter(Context context){ this.mContext=context; this.mInflater=LayoutInflater.from(mContext); mList=new ArrayList<>();//防止为设置数据源时为空 } //设置数据源 public void setDataSource(List<AVUser> list){ this.mList=list; } //创建ViewHolder @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ContactHolder holder=new ContactHolder(mInflater.inflate(R.layout.contact_select_recyclerview_item,parent,false)); return holder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { //不使用 使用3个参数的重载函数 } //绑定ViewHolder中的资源 使用三个参数的onBindViewHolder @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position,List payloads) { final ContactHolder contact= (ContactHolder) holder; if(payloads.isEmpty()){//payloads即有效负载,当首次加载或调用notifyDatasetChanged() ,notifyItemChange(int position)进行刷新时,payloads为empty 即空 AVUser user=mList.get(position); contact.userName.setText(user.getString("name")); contact.userId.setText(String.format("工号ID:%d",user.getInt("employeeId"))); AVFile img=user.getAVFile("portrait"); Glide.with(mContext).load(img.getUrl()) .centerCrop() .transform(new GlideCircleTransform(mContext)) .dontAnimate() .placeholder(R.drawable.dayhr_userphoto_def) .into(contact.userImg); contact.checkBox.setChecked(mSelectedPos==position); }else{//当调用notifyItemChange(int position, Object payload)进行布局刷新时,payloads不会empty ,所以真正的布局刷新应该在这里实现 重点! contact.checkBox.setChecked(mSelectedPos==position); } holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(mSelectedPos!=position){//当前选中的position和上次选中不是同一个position 执行 contact.checkBox.setChecked(true); if(mSelectedPos!=-1){//判断是否有效 -1是初始值 即无效 第二个参数是Object 随便传个int 这里只是起个标志位 notifyItemChanged(mSelectedPos,0); } mSelectedPos=position; } } }); } //提供给外部Activity来获取当前checkBox选中的item,这样就不用去遍历了 重点! public int getSelectedPos(){ return mSelectedPos; } @Override public int getItemCount() { return mList.size(); } public class ContactHolder extends RecyclerView.ViewHolder{ public CheckBox checkBox;//单选框 重点! public TextView userName; public TextView userId; public ImageView userImg; public ContactHolder(View itemView) { super(itemView); checkBox= (CheckBox) itemView.findViewById(R.id.ContactSelect_list_item_checkBox); userName= (TextView) itemView.findViewById(R.id.ContactSelect_list_item_user_name); userId= (TextView) itemView.findViewById(R.id.ContactSelect_list_item_user_employeeId); userImg= (ImageView) itemView.findViewById(R.id.ContactSelect_list_item_img); } }
Activity:
mRecyclerView= (RecyclerView) findViewById(R.id.ContactSelectActivity_recyclerView); mRecyclerView.setLayoutManager(new LinearLayoutManager(this));//设置布局管理器 为线性布局 mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));//设置分割线 mAdapter=new ContactSelectAdapter(this); mRecyclerView.setAdapter(mAdapter); mAdapter.setDataSource(list); mAdapter.notifyDataSetChanged();
布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@android:color/white" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="20dp" android:paddingTop="10dp" android:paddingBottom="10dp" android:paddingRight="20dp" > <CheckBox android:id="@+id/ContactSelect_list_item_checkBox" android:layout_width="20dp" android:layout_height="20dp" android:layout_centerVertical="true" android:button="@null" android:enabled="false" android:background="@drawable/contact_select_list_item_checkbox_bg"/> <ImageView android:id="@+id/ContactSelect_list_item_img" android:layout_width="40dp" android:layout_height="40dp" android:layout_toRightOf="@id/ContactSelect_list_item_checkBox" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_centerVertical="true" android:src="@drawable/dayhr_userphoto_def"/> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@id/ContactSelect_list_item_img"> <TextView android:id="@+id/ContactSelect_list_item_user_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/black" android:text="马云" android:textSize="16sp" /> <TextView android:id="@+id/ContactSelect_list_item_user_employeeId" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="工号:1008" /> </LinearLayout> </RelativeLayout>
最重点的还是RecyclerView中的onBindViewHolder的三个参数的方法
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position,List payloads)
和notifyItemChanged的两个参数的方法
public final void notifyItemChanged(int position, Object payload)
接下来分析这两个方法的介绍 详情见下一章博客
http://blog.csdn.net/qq402164452/article/details/53464091
相关文章推荐
- Android Recyclerview实现多选,单选,全选,反选,批量删除的功能
- android实现RecyclerView列表单选功能
- Android RecyclerView+StaggerLayoutManager实现瀑布流单选item乱跳
- 【Android】 RecyclerView、ListView实现单选列表的优雅之路.
- Android ListView、RecyclerView两种方式实现聊天界面搭建
- <Android 基础(三十五)> RecyclerView多类型Item的正确实现姿势
- Android RecyclerView粘性头部的两种实现方式
- Android RecyclerView、ListView实现单选列表的优雅之路.
- Android 基础(三十五)~ RecyclerView多类型Item的正确实现姿势
- 【Android】 RecyclerView、ListView实现单选列表的优雅之路.
- Android RecyclerView中实现自定义GridView的方式(实现不同item)
- Android 实现RecyclerView嵌套RecyclerView 实现购物车的全选 反选 单选 商家全选
- Android RecyclerView 真正的布局刷新的正确方式
- android 三种实现水平向滑动方式(ViewPager、ViewFilpper、ViewFlow)的比较
- Android 自定义RecyclerView 实现真正的Gallery效果
- Android 自定义RecyclerView 实现真正的Gallery效果
- Android 自定义RecyclerView 实现真正的Gallery效果
- Android 自定义RecyclerView 实现真正的Gallery效果
- android 三种实现水平向滑动方式(ViewPager、ViewFilpper、ViewFlow)的比较
- Android 简单最实用的方式实现ViewPager无限循环两种方式