RecycleView实现长按多选全选删除功能

一、功能:

recycleView横向列表,实现item添加,长按选择,全选,全不选的删除,滑动删除功能。

用realm构建数据库存储列表数据。用FloatingActionButton 作为添加按钮。

思路:

activity页面最下面添加一个带有删除tab的view,当长按item的时候,view显示出来。

adapter的itemview里面,带有一个checkbox,长按item的时候,checkbox显示出来。

adapter里面添加一个是否删除模式的boolen型判断对象inDeletionMode,和一个Set<Users> selectedUsers被选中删除列表。

长按item的时候,inDeletionMode设置为true,并且notifydatasetChanged,更新Bindviewholder的视图,让checkbox显示出来,

删除模式的时候,checkbox为true的时候,将该位置的user添加到设selectedUsers里面。

点击全选、全不选的时候,更新adapter里面的selectedUsers对象,并且更新视图显示。

realm的使用参考:realm详解

效果图:

效果图

二、实现

1、activity

xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/btn_floating"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_gravity="right|bottom"
        android:layout_margin="16dp"
        android:src="@mipmap/add_user"
        android:backgroundTint="@color/light_gray"
        app:rippleColor="@color/login_line_color"/>

    <LinearLayout
        android:id="@+id/ll_delete"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:background="@color/white"
        android:gravity="center"
        android:orientation="vertical"
        android:visibility="gone">

        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:background="@color/color_text_hint"/>

        <com.landicorp.dependencelibrary.widget.TabView
            android:id="@+id/tab_delete"
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:paddingBottom="16dp"
            app:color="@color/color_text_normal"
            app:icon="@mipmap/delete"
            app:text="删除"
            app:text_size="12sp"/>

    </LinearLayout>

</RelativeLayout>

activity:


/**
 * 用户列表,可长按删除,滑动删除,新增用户
 */

public class VIPActivity extends BusinessActivity implements View.OnClickListener, UserAdapter.onItemClickListener {

    private RecyclerView recyclerView;
    private FloatingActionButton btnFloating;
    private TabView tabDelete;
    private LinearLayout llDelete;

    private RealmResults<Users> usersList;
    private UserAdapter adapter;
    Realm realm;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vip);
        realm = Realm.getDefaultInstance();
        initView();
        setTitle("VIP列表");
        //全选按钮设置监听
        getRlTextAheadView().setOnClickListener(this);
    }

    //初始化view,recycleView添加适配器,绑定ItemTouchHelper
    private void initView() {
        usersList = realm.where(Users.class).findAll();
        adapter = new UserAdapter();
        adapter.setUsersList(usersList);
        adapter.setListener(this);
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        btnFloating = (FloatingActionButton) findViewById(R.id.btn_floating);
        tabDelete = (TabView) findViewById(R.id.tab_delete);
        llDelete = (LinearLayout) findViewById(R.id.ll_delete);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        recyclerView.setAdapter(adapter);
        //将touchhelper和recycleview绑定,实现滑动删除,但是不能实现上下拖拽item,因为realm不支持Collection.swap方式
        //这里自定义了一个callback实现了ItemTouchHelper.Callback接口方法,传入adapter对象相应滑动删除事件
        ItemTouchHelper.Callback callback = new MyItemHelpCallBack(adapter);
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        touchHelper.attachToRecyclerView(recyclerView);

        btnFloating.setOnClickListener(this);
        tabDelete.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_floating:
                addUser();
                break;
            case R.id.tab_delete:
                if (llDelete.isShown()) {
                    deleteUsers();
                    hideAhead();
                    llDelete.setVisibility(View.GONE);
                    btnFloating.setVisibility(View.VISIBLE);
                    adapter.setInDeletionMode(false);
                }
                break;
            case R.id.rl_head_text:
                seletAllOrNot();
                break;
            default:
                break;
        }
    }

    //添加对象
    public void addUser() {
        DialogUtils.showAddUserDialog(this, "添加用户", new AddUserDialog.onAddUserListener() {
            @Override
            public void addUser(String name, String cardNo) {
                realm.beginTransaction();
                Users user = realm.createObject(Users.class);
                user.setName(name);
                user.setCardNo(cardNo);
                realm.commitTransaction();
            }
        });
    }

    //删除选中对象
    public void deleteUsers() {
        Set<Users> selectSet = adapter.getSelectSet();
        realm.beginTransaction();
        Iterator<Users> iterator = selectSet.iterator();
        while (iterator.hasNext()) {
            Users user = iterator.next();
            if (usersList.contains(user)) {
                user.deleteFromRealm();
            }
        }
        realm.commitTransaction();
    }

    //点击全选,全不选,状态切换
    private void seletAllOrNot() {
        if (adapter.getSelectSet().size() < usersList.size()) {
            Set<Users> selectSet = adapter.getSelectSet();
            for (int i = 0; i < usersList.size(); i++) {
                selectSet.add(usersList.get(i));
            }
            adapter.setSelectSet(selectSet);
            adapter.notifyDataSetChanged();
            setAheadText("全不选");
        } else {
            adapter.setSelectSet(new HashSet<Users>());
            adapter.notifyDataSetChanged();
            setAheadText("全选");
        }
    }

    @Override
    public void onItemClick(final Users user) {
       //listitem 点击事件
    }

    //长按item,隐藏floatingbtn,显示全选按钮,
    //通知adapter变为删除选择模式,将当前选中的item的checkbox设置为true
    @Override
    public void onItemLongCick(Users user) {
        if (!llDelete.isShown()) {
            showTextAhead();
            setAheadText("全选");
            llDelete.setVisibility(View.VISIBLE);
            btnFloating.setVisibility(View.GONE);
            Set<Users> selectSet = new HashSet<>();
            selectSet.add(user);
            adapter.setSelectSet(selectSet);
            adapter.setInDeletionMode(true);
        }
    }


    //滑动删除item
    @Override
    public void onSwipeToDeleteUser(int position) {
        if (usersList.size() >= position) {
            realm.beginTransaction();
            usersList.get(position).deleteFromRealm();
            realm.commitTransaction();

            adapter.notifyDataSetChanged();
        }
    }

    //activity监听到adapter选择了全部的item,全选变成全不选
    @Override
    public void selectedAll() {
        setAheadText("全不选");
    }

    //点击返回按钮,如果是删除状态,取消删除
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (llDelete.isShown()) {
            llDelete.setVisibility(View.GONE);
            btnFloating.setVisibility(View.VISIBLE);
            hideAhead();
            adapter.setInDeletionMode(false);
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

    //关闭realm,防止内存泄漏
    @Override
    protected void onDestroy() {
        super.onDestroy();
        realm.close();
    }
}

2、adapter

item.xml

<?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="48dp"
    android:background="@color/white"
    android:gravity="center_vertical"
    android:paddingLeft="16dp"
    android:paddingRight="16dp">


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="3">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1.8"
            android:gravity="center_vertical"
            android:padding="5dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="姓名:"
                android:textColor="@color/color_text_normal"
                android:textSize="14sp"/>

            <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:textColor="@color/color_text_normal"
                android:textSize="14sp"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1.2"
            android:paddingLeft="5dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="卡号:"
                android:textColor="@color/color_text_hint"
                android:textSize="12sp"/>

            <TextView
                android:id="@+id/tv_cardNo"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:textColor="@color/color_text_hint"
                android:textSize="12sp"/>

        </LinearLayout>
    </LinearLayout>

    <CheckBox
        android:id="@+id/checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginTop="10dp"
        android:visibility="gone"/>
</RelativeLayout>

adapter:

/**
 * 用户列表适配器
 */

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> implements View.OnClickListener
        , View.OnLongClickListener {

    private RealmResults<Users> usersList;

    private onItemClickListener listener;

    //设置显示的数据
    public void setUsersList(RealmResults<Users> usersList) {
        this.usersList = usersList;
    }

    //设置监听器
    public void setListener(onItemClickListener listener) {
        this.listener = listener;
    }

    //是否删除模式
    private boolean inDeletionMode = false;

    //设置是否为删除模式,改变绑定视图
    public void setInDeletionMode(boolean inDeletionMode) {
        this.inDeletionMode = inDeletionMode;
        notifyDataSetChanged();
    }

    //选中要删除用户
    private Set<Users> selectSet = new HashSet<>();

    /**
     * 获取选中要删除的列表
     *
     * @return
     */
    public Set<Users> getSelectSet() {
        return selectSet;
    }

    public void setSelectSet(Set<Users> selectSet) {
        this.selectSet = selectSet;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        //这里调用realm的isValid方法,判断当前数据是否可用,防止出现数据被删除仍然使用导致崩溃
        if (usersList.get(position).isValid()) {

            holder.tvName.setText(usersList.get(position).getName());
            holder.tvCardNo.setText(usersList.get(position).getCardNo());
            //删除模式,checkbox显示,否则不显示
            holder.checkbox.setVisibility(inDeletionMode ? View.VISIBLE : View.GONE);


            if (inDeletionMode) {
                holder.rootView.setOnClickListener(null);
                holder.rootView.setOnLongClickListener(null);

                //设置当前item的checkbox是否为选中状态
                //item长按删除的时候,activity设置了当前长按的item对象保存在selectset里面了
                holder.checkbox.setChecked(selectSet.contains(usersList.get(position)));
                holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if (isChecked) {
                            selectSet.add(usersList.get(position));
                        } else {
                            selectSet.remove(usersList.get(position));
                        }

                        //全部选中,通知activity “全选” 变成 “全不选”
                        if (selectSet.size() == usersList.size()) {
                            listener.selectedAll();
                        }
                    }
                });
            } else {
                holder.checkbox.setOnCheckedChangeListener(null);
                holder.rootView.setOnClickListener(this);
                holder.rootView.setOnLongClickListener(this);
            }

            holder.itemView.setTag(usersList.get(position));
        }
    }

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

    @Override
    public void onClick(View v) {
        Users user = (Users) v.getTag();
        if (null != user && listener != null) {
            listener.onItemClick(user);
        }
    }

    @Override
    public boolean onLongClick(View v) {
        Users user = (Users) v.getTag();
        if (null != user && listener != null) {
            listener.onItemLongCick(user);
        }
        return true;
    }

    public void swapData(int from, int to) {
        //This method is not supported by 'RealmResults' or 'OrderedRealmCollectionSnapshot'.
        Collections.swap(usersList, from, to);
    }

    public void swipeDelete(int position) {
        if (null != listener) {
            listener.onSwipeToDeleteUser(position);
        }
    }


    public static class ViewHolder extends RecyclerView.ViewHolder {
        public View rootView;
        public TextView tvName;
        public TextView tvCardNo;
        public CheckBox checkbox;

        public ViewHolder(View rootView) {
            super(rootView);
            this.rootView = rootView;
            this.tvName = (TextView) rootView.findViewById(R.id.tv_name);
            this.tvCardNo = (TextView) rootView.findViewById(R.id.tv_cardNo);
            this.checkbox = (CheckBox) rootView.findViewById(R.id.checkbox);
        }

    }

    public interface onItemClickListener {
        void onItemClick(Users user);

        void onItemLongCick(Users user);

        void onSwipeToDeleteUser(int position);

        void selectedAll();
    }

}

注:realm给recycleview提供了官方的适配器,很好用,只不过我这次没有用

Realm官方RecycleView适配器demo

3、自定义ItemTouchHelperCallBack

/**
 * 自定义ItemTouchHelper.Callback
 */

public class MyItemHelpCallBack extends ItemTouchHelper.Callback {

    private UserAdapter adapter;

    public MyItemHelpCallBack(UserAdapter adapter) {
        this.adapter = adapter;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; //允许上下的拖动
        int swipeFlags = ItemTouchHelper.LEFT; //只允许从右向左侧滑
        return makeMovementFlags(dragFlags, swipeFlags);

    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        //This method is not supported by 'RealmResults' or 'OrderedRealmCollectionSnapshot'.
        //realm 不支持 Collections.swap()方法
        //        adapter.swapData(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        adapter.swipeDelete(viewHolder.getAdapterPosition());
    }
}

猜你喜欢

转载自blog.csdn.net/hpp_1225/article/details/84301009
今日推荐