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中数据绑定的集合需要更换

在这里插入图片描述

其他的都是一样的了:

附上DEMO下载地址:

GITHUB:https://github.com/muyexiaogui/FlowTagDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值