欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

RecyclerView实现流式标签单选多选功能

程序员文章站 2022-05-31 12:43:04
recyclerview简介 recyclerview是android一个更强大的控件,其不仅可以实现和listview同样的效果,还有优化了listview中的各种不足。其可以实现...

recyclerview简介

recyclerview是android一个更强大的控件,其不仅可以实现和listview同样的效果,还有优化了listview中的各种不足。其可以实现数据纵向滚动,也可以实现横向滚动(listview做不到横向滚动)。接下来讲解recyclerview的用法。

recyclerview 基本用法

因为recyclerview属于新增的控件,android将recyclerview定义在support库里。若要使用recyclerview,第一步是要在build.gradle中添加对应的依赖库。

一、实现效果

单选效果:

RecyclerView实现流式标签单选多选功能

多选效果:

RecyclerView实现流式标签单选多选功能

二、前期准备

依赖的添加:

  //瀑布流layoutmanager
  implementation 'com.google.android:flexbox:1.0.0' 
  //recyclerview
  implementation 'com.android.support:design:28.0.0'

三、使用方法

3.1、多选的实现

1、使用集合存储需要存储或者展示的数据

public static set<integer> positionset = new hashset<>(); //用于存储选择的位置
  private boolean selectmode = true; //选择模式 多选或者单选 true 多选
  public set<string> checktypenameset = new hashset<>(); //用于存储选择项的名称

2、实现流式布局的布局管理器

 mrecyclerview = (recyclerview) findviewbyid(r.id.recycler);
    flexboxlayoutmanager manager = new flexboxlayoutmanager(this, flexdirection.row, flexwrap.wrap){
      @override
      public boolean canscrollvertically() {
        return false;
      }
    };
    mrecyclerview.setlayoutmanager(manager);

3、单条点击事件的处理

madapter.setonitemclicklistener(new onitemclicklistener() {
      @override
      public void onitemclick(view view, int position) {
        addorremove(position);
      }
      @override
      public void onitemlongclick(view view, int position) {
      }
    });
 private void addorremove(int position) {
    if (positionset.contains(position)) {
      // 如果包含,则撤销选择
      positionset.remove(position);
      checktypenameset.remove(mlistdata.get(position).gettagname());
    } else {
      // 如果不包含,则添加
      positionset.add(position);
      checktypenameset.add(mlistdata.get(position).gettagname());
    }
    if (positionset.size() == 0) {
      // 如果没有选中任何的item,则退出多选模式
      madapter.notifydatasetchanged();
      selectmode = false;
    } else {
      // 更新列表界面,否则无法显示已选的item
      madapter.notifydatasetchanged();
    }
    log.e("info",positionset.tostring());
    toast.maketext(multiplechoiceactivity.this,checktypenameset.tostring(),toast.length_short).show();
  }

4、适配的写法

public class multiplerecycleradapter extends recyclerview.adapter<multiplerecycleradapter.viewholder> {
  private context mcontext;
  private list<testbean> mlistdata = new arraylist<>();
  private onitemclicklistener monitemclicklistener;
  public void setonitemclicklistener(onitemclicklistener monitemclicklistener) {
    this.monitemclicklistener = monitemclicklistener;
  }
  public multiplerecycleradapter(context mcontext, list<testbean> mlistdata) {
   // mlistdata = new arraylist<>();
    this.mcontext = mcontext;
    this.mlistdata = mlistdata;
  }
  public void update(list<testbean> list){
    if(list != null && list.size() > 0){
      mlistdata.addall(list);
      notifydatasetchanged();
    }
  }
  class viewholder extends recyclerview.viewholder{
    textview typetv;
    checkablelayout rootlayout;
    public viewholder(@nonnull view itemview) {
      super(itemview);
      typetv = (textview) itemview.findviewbyid(r.id.alive_type_tv);
      rootlayout = (checkablelayout) itemview.findviewbyid(r.id.root_layout);
    }
  }
  @nonnull
  @override
  public viewholder oncreateviewholder(@nonnull viewgroup viewgroup, int i) {
    if(mcontext == null){
      mcontext = viewgroup.getcontext();
    }
    view view = layoutinflater.from(mcontext).inflate(r.layout.item_recycler,viewgroup,false);
    return new viewholder(view);
  }
  @override
  public void onbindviewholder(@nonnull final viewholder holder, int position) {
    set<integer> positionset = multiplechoiceactivity.positionset;
    //检查set里是否包含position,包含则显示选中的背景色,不包含则反之
    if (positionset.contains(position)) {
      holder.rootlayout.setchecked(true);
      holder.typetv.settextcolor(mcontext.getresources().getcolor(r.color.white));
    } else {
      holder.rootlayout.setchecked(false);
      holder.typetv.settextcolor(mcontext.getresources().getcolor(r.color.grey_60));
    }
    testbean bean = mlistdata.get(position);
    holder.typetv.settext(bean.gettagname());
    if(monitemclicklistener != null) {
      holder.itemview.setonclicklistener(new view.onclicklistener() {
        @override
        public void onclick(view view) {
          int pos = holder.getlayoutposition();
          monitemclicklistener.onitemclick(holder.itemview, pos);
          holder.rootlayout.setchecked(true);
        }
      });
    }
  }
  @override
  public int getitemcount() {
    return mlistdata != null ? mlistdata.size() : 0;
  }
}

5、单条布局的xml文件

<?xml version="1.0" encoding="utf-8"?>
<com.lhx.flowtagdemo.recycler.checkablelayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_marginleft="8dp"
  android:layout_margintop="6dp"
  android:id="@+id/root_layout"
  android:background="@drawable/type_select_bg_color"
  xmlns:tools="http://schemas.android.com/tools">
  <textview
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingright="18dp"
    android:paddingleft="18dp"
    android:gravity="center"
    android:textsize="14sp"
    tools:text="医药"
    android:id="@+id/alive_type_tv"
    android:textcolor="#60000000"
    android:paddingbottom="10dp"
    android:paddingtop="10dp" />
</com.lhx.flowtagdemo.recycler.checkablelayout>

6、checkablelayout的使用说明:

实现了checkable接口,可用于布局的选择,设置选择的样式

public class checkablelayout extends relativelayout implements checkable {
  private static final int[] checked_state_set = {android.r.attr.state_checked};
  private boolean mchecked;
  public checkablelayout(context context, attributeset attrs) {
    super(context, attrs);
  }
  @override
  public void setchecked(boolean b) {
    if (b != mchecked){
      mchecked = b;
      refreshdrawablestate();
    }
  }
  @override
  public boolean ischecked() {
    return mchecked;
  }
  @override
  public void toggle() {
    setchecked(!mchecked);
  }
  @override
  protected int[] oncreatedrawablestate(int extraspace) {
    final int[] drawablestate = super.oncreatedrawablestate(extraspace + 1);
    if (ischecked()) mergedrawablestates(drawablestate, checked_state_set);
    return drawablestate;
  }
}

3.2、单选的实现

单选和多选的代码几乎完全一致, 只需要修改一部分

1、去除记录选择名称的集合, 将选择模式设置为false

public static set<integer> positionset = new hashset<>();
  private boolean selectmode = false; //选择模式 多选或者单选 true 多选

2 、单条点击事件需要进行修改

madapter.setonitemclicklistener(new onitemclicklistener() {
      @override
      public void onitemclick(view view, int position) {
        if (selectmode) {
          // 如果当前处于多选状态,则进入多选状态的逻辑
          // 维护当前已选的position
          addorremove(position);
        } else {
          // 如果不是多选状态,则进入单选事件的业务逻辑
          if (!positionset.contains(position)) {
            // 选择不同的单位时取消之前选中的单位
            positionset.clear();
          }
          addorremove(position);
        }
        string kindname = mlistdata.get(position).gettagname();
        toast.maketext(singlechoiceactivity.this, kindname, toast.length_short).show();
      }
      @override
      public void onitemlongclick(view view, int position) {
      }
    });
 private void addorremove(int position) {
    if (positionset.contains(position)) {
      // 如果包含,则撤销选择
      positionset.remove(position);
    } else {
      // 如果不包含,则添加
      positionset.add(position);
    }
    if (positionset.size() == 0) {
      // 如果没有选中任何的item,则退出多选模式
      madapter.notifydatasetchanged();
      selectmode = false;
    } else {
      // 更新列表界面,否则无法显示已选的item
      madapter.notifydatasetchanged();
    }
  }

3、adapter中数据绑定的集合需要更换

RecyclerView实现流式标签单选多选功能

其他的都是一样的了:

附上demo下载地址:

github:https://github.com/muyexiaogui/flowtagdemo

总结

以上所述是小编给大家介绍的recyclerview实现流式标签单选多选功能,希望对大家有所帮助