recyclerview 列表的item 拖拽 置顶 全选 删除 功能

        很多时候我们需要对列表进行一些操作,比如说股票的自选列表 我们希望能够拖拽删除置顶等操作。在recyclerveiw 之前 我们使用listview 完成这些操作 有点点麻烦,但是在recyclerview 出来之后ItemTouchHelper类使得一切变得简单。

       先上图看下效果

 /**
     * Creates an ItemTouchHelper that will work with the given Callback.
     * <p>
     * You can attach ItemTouchHelper to a RecyclerView via
     * {@link #attachToRecyclerView(RecyclerView)}. Upon attaching, it will add an item decoration,
     * an onItemTouchListener and a Child attach / detach listener to the RecyclerView.
     *
     * @param callback The Callback which controls the behavior of this touch helper.
     */
    public ItemTouchHelper(Callback callback) {
        mCallback = callback;
    }

在我们创建 ItemTouchHelper 的时候 需要 传递一个Callback 对象。 官方的解释是 控制触摸事件的回调。也就是监听我们对列表的拖拽事件。我们看看callback 中具体我们要重写哪些回调

第一个就是  getMovementFlags 。

 /**
     * getMovementFlags 这个方法中我们可以设置拖拽和侧滑的方向 比如说我们现在是纵向列表 拖拽 设置
     * makeMovementFlags(dragFlags, 0);第一个参数是拖拽的方向 ,我们设置的是ItemTouchHelper.UP | ItemTouchHelper.DOWN
     * 上或者下、因为我们没有侧滑的需求所以swipeFlags 设置了0  如果我们的列表是网格列表 gridview
     * 我们也可以根据 recyclerView.getLayoutManager() 来判断 然后
     * 设置 ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT
     *
     *  如果是侧滑 我们需要把swipeFlags 设置成ItemTouchHelper.START | ItemTouchHelper.END
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN ;
        return makeMovementFlags(dragFlags, 0);
    }

第二个方法是 onMove 每次 拖动都会触发这个回调,每次回调我们可以在我们 adapter 中 操作我们的数据 每次拖动后我们把我们列表绑定书数组里 数据的位置也做下调整。

 /**
     * 顾名思义 当我们把一个 item 从一个位置拖到另一个位置 会触发这个回调
     * @param recyclerView
     * @param viewHolder ;老的 位置
     * @param target  新的位置
     * @return
     */
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        interfaceTouchHelper.onItemMove(viewHolder, viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }
public void onItemMove(RecyclerView.ViewHolder holder, int fromPosition, int toPosition) {

        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(data, i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(data, i, i - 1);
            }
        }
        //刷新列表
        notifyItemMoved(fromPosition, toPosition);
    }

其他 需要重写的方法

/**
     * 当选中的时候对 item进行 设置效果 放大 缩小 或者高亮
     * @param viewHolder
     * @param actionState
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            interfaceTouchHelper.onItemSelect(viewHolder);
        }
        super.onSelectedChanged(viewHolder,actionState);
    }

    /**
     * 拖拽 结束后 我们 要对之前 做的 效果进行清除。 恢复正常状态
     * @param recyclerView
     * @param viewHolder
     */
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        if (!recyclerView.isComputingLayout()) {
            interfaceTouchHelper.onItemClear(viewHolder);
        }
        super.clearView(recyclerView,viewHolder);
    }

  /**
     * 如果我们需要动态设置 能否拖动,则重写 isLongPressDragEnabled()方法 动态赋值,默认是true 的
     * @return
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return isDrag;
    }

我们写一个接口类 来处理选中 置顶 等 操作 

public interface InterfaceOnCheckOrClickListener {
    /**
     * 点击拖动
     */
    void onViewDragStart(MotionEvent event);

    /**
     * 停止拖动
     */
    void onViewDragStop();

    /**
     * 置顶点击事件
     * @param view
     * @param position
     */
    void onViewClick(View view, int position);

    /**
     * 选中的CheckBox
     * @param view
     * @param position
     */
    void onCheckBoxSelected(View view, int position);
}

在我们的activity 中 继承这个接口 重写 onViewClick 方法

 /**
     * 点击置顶
     * @param view
     * @param position
     */
    @Override
    public void onViewClick(View view, int position) {
        for (int i = position; i > 0; i--) {
            Collections.swap(myAdapter.getData(), i, i - 1);
        }
        myAdapter.notifyDataSetChanged();
    }

还有一些具体的代码实现不再赘述 直接上源码吧。

代码地址 :https://github.com/fyhsgsgssg/RecyclerViewTouchHelper

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章