RecyclerView的长按多选功能

RecyclerView的长按多选功能

主要实现功能

  • 长按进入删除模式(使用的android官方提供的actionMode)
  • 对点击的item进行标记(对item设置背景色)
  • 点击ActionMode上的menu进行点击实现删除选中的item

思路

其实思路很简单,用一个HashSet保存RecyclerView的所点击的item的位置,点击删除后要操作RV中的原数据,再执行RecyclerView的notifyDataSetChanged()方法更新数据便好。

运行截图

初始状态

这里写图片描述

长按后进入ActionMode

这里写图片描述

代码

adapter
public class RvAdapter extends RecyclerView.Adapter<RvHolder>  {
    private List<String> items;
    private LayoutInflater inflater;
    private Context context;


    private OnItemClickListener onItemClickListener;

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public RvAdapter(Context context, List<String> items){
        this.items = items;
        this.context = context;
        inflater = LayoutInflater.from(context);
    }
    @Override
    public RvHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.item,parent,false);
        RvHolder holder = new RvHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(RvHolder holder, final int position) {
        holder.setData(items.get(position),position);
        if (onItemClickListener!=null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onItemClickListener.onItemClick(v,position);
                }
            });
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    onItemClickListener.onItemLongClick(v,position);
                    return false;
                }
            });
        }
    }

    public void remove(String str){
        items.remove(str);
        notifyDataSetChanged();
    }

    public String getItem(int pos){
        return items.get(pos);
    }

    @Override
    public int getItemCount() {
        return items.size();
    }



    public interface OnItemClickListener{
        void onItemClick(View view, int position);
        void onItemLongClick(View view,int position);
    }

}
ViewHolder
class RvHolder extends RecyclerView.ViewHolder  {
    private TextView textView;

    public RvHolder(View itemView) {
        super(itemView);
        textView = (TextView) itemView.findViewById(R.id.tv);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void setData(String item, int position){
        Set<Integer> positionSet = MainActivity.instance.positionSet;
        if (positionSet.contains(position)) {
            itemView.setBackground(MainActivity.instance.getResources().getDrawable(R.drawable.bg_selected));
        } else {
            itemView.setBackground(MainActivity.instance.getResources().getDrawable(R.drawable.btn_common));
        }
        textView.setText(item);
    }

}
Activity
public class MainActivity extends AppCompatActivity implements ActionMode.Callback {
    private ActionMode actionMode;
    public Set<Integer> positionSet = new HashSet<>();
    private RvAdapter adapter;

    public static MainActivity instance;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        instance = this;
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        List<String> items = new ArrayList<>();
        for (int i=1;i<=20;i++){
            items.add("第"+i+"个item");
        }

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv);
        adapter = new RvAdapter(this,items);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        adapter.setOnItemClickListener(new RvAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                if (actionMode != null) {
                    // 如果当前处于多选状态,则进入多选状态的逻辑
                    // 维护当前已选的position
                    addOrRemove(position);
                } else {
                    // 如果不是多选状态,则进入点击事件的业务逻辑
                    // TODO something
                }
            }

            @Override
            public void onItemLongClick(View view, int position) {
                if (actionMode == null) {
                    actionMode = startSupportActionMode(MainActivity.this);
                }
            }
        });


    }

    private void addOrRemove(int position) {
        if (positionSet.contains(position)) {
            // 如果包含,则撤销选择
            positionSet.remove(position);
        } else {
            // 如果不包含,则添加
            positionSet.add(position);
        }
        if (positionSet.size() == 0) {
            // 如果没有选中任何的item,则退出多选模式
            actionMode.finish();
        } else {
            // 设置ActionMode标题
            actionMode.setTitle(positionSet.size() + " 已选择");
            // 更新列表界面,否则无法显示已选的item
            adapter.notifyDataSetChanged();
        }
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        if (actionMode == null) {
            actionMode = mode;
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.menu_delete, menu);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_delete:
                // 删除已选
                Set<String> valueSet = new HashSet<>();
                for (int position : positionSet) {
                    valueSet.add(adapter.getItem(position));
                }
                for (String val : valueSet) {
                    adapter.remove(val);
                }
                mode.finish();
                return true;
            default:
                return false;
        }
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        actionMode = null;
        positionSet.clear();
        adapter.notifyDataSetChanged();
    }
}

注意

因为博主是个android初学者,这个问题耗费最长时间的地方是解决RV滑动item选中位置显示错位,要在onBindViewHolder中设置每一个item的背景色,否则RV在回收的过程中会将你在点击的时候设置的背景色回收,滑动的时候会造成错乱。

代码地址:

http://download.csdn.net/detail/srtianxia/9369762
https://github.com/srtianxia/RvSelectDemo

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在安卓的RecyclerView中实现多选并删除子项的功能,您可以按照以下步骤进行: 1. 实现一个按事件监听器,可以在用户按某个子项时被触发。 ```java public interface OnItemLongClickListener { void onItemLongClick(View view, int position); } ``` 2. 在RecyclerView的Adapter中设置一个按事件监听器和一个选中状态的数组。 ```java public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private OnItemLongClickListener onItemLongClickListener; private boolean[] selected; public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) { this.onItemLongClickListener = onItemLongClickListener; } public void setSelected(boolean[] selected) { this.selected = selected; } // ... @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { // ... holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (onItemLongClickListener != null) { onItemLongClickListener.onItemLongClick(v, position); } return true; } }); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { selected[position] = !selected[position]; notifyItemChanged(position); } }); if (selected[position]) { holder.itemView.setBackgroundColor(Color.RED); } else { holder.itemView.setBackgroundColor(Color.WHITE); } } // ... } ``` 3. 在Activity或Fragment中实现该按事件监听器,并在其中实现多选删除。 ```java myAdapter.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public void onItemLongClick(View view, int position) { // 初始化选中状态数组 boolean[] selected = new boolean[myDataset.size()]; Arrays.fill(selected, false); selected[position] = true; myAdapter.setSelected(selected); myAdapter.notifyDataSetChanged(); // 显示删除按钮 deleteButton.setVisibility(View.VISIBLE); deleteButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 删除选中的子项 for (int i = selected.length - 1; i >= 0; i--) { if (selected[i]) { myDataset.remove(i); myAdapter.notifyItemRemoved(i); } } // 隐藏删除按钮 deleteButton.setVisibility(View.GONE); // 重置选中状态数组 Arrays.fill(selected, false); myAdapter.setSelected(selected); myAdapter.notifyDataSetChanged(); } }); } }); ``` 这样,当用户按某个子项时,就会触发相应的按事件监听器,并进入多选删除模式。用户可以单击每个子项来选择或取消选择,选择完成后,用户可以点击删除按钮来删除选中的子项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值