RecyclerView之拖拽滑动

recyclerview控件大家已经用的非常熟悉了,最近开发时做仿微信发送朋友圈注意到微信选完图片之后可以对图片进行拖拽删除,所以进行了尝试,其实recyclerview本身已经提供了帮助类,主要是继承其回调,下面对代码进行讲解分析。

public class RecyclerCallBack extends ItemTouchHelper.Callback {

    private int dragFlags;
    private int swipeFlags;
    private ImgAdapter adapter;
    private boolean up;
    private Context mContext;

    public RecyclerCallBack(Context context, ImgAdapter adapter) {
        this.adapter = adapter;
        this.mContext = context;
    }

    /**
     * 设置item是否处理拖拽事件和滑动事件,以及拖拽和滑动操作的方向 .
     * 如果直接返回0 表明不支持进行拖动和滑动 .
     * @param recyclerView .
     * @param viewHolder  .
     * @return .
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //判断 recyclerView的布局管理器数据
        if (recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
             //表示可以对其进行上下左右的拖动
             dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            //0则不响应事件
            swipeFlags = 0;
        }
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    /**
     * 当用户从item原来的位置拖动可以拖动的item到新位置的过程中调用 .
     * @param recyclerView .
     * @param viewHolder .
     * @param target .
     * @return .
     */
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        int fromPosition = viewHolder.getAdapterPosition();
        int toPosition = target.getAdapterPosition();
        if (toPosition == adapter.getDatas().size() - 1 || adapter.getDatas().size() - 1 == fromPosition) {
            return true;
        }
        //表示对数据进行新的排序 .
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(adapter.getDatas(), i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(adapter.getDatas(), i, i - 1);
            }
        }
        adapter.notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    /**
     * 设置是否支持长按拖拽 .
     * @return .
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return false;
    }

    /**
     * @param viewHolder .
     * @param direction .
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

    }

    /**
     * 当用户与item的交互结束并且item也完成了动画时调用 .
     * @param recyclerView .
     * @param viewHolder .
     */
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        adapter.notifyDataSetChanged();
        initData();
        if (dragListener != null) {
            dragListener.clearView();
        }
    }

    /**
     * 重置 .
     */
    private void initData() {
        if (dragListener != null) {
            dragListener.deleteState(false);
            dragListener.dragState(false);
        }
        up = false;
    }

    /**
     * 自定义拖动与滑动交互 .
     * @param c  .
     * @param recyclerView .
     * @param viewHolder .
     * @param dX .
     * @param dY .
     * @param actionState .
     * @param isCurrentlyActive .
     */
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        if (null == dragListener) {
            return;
        }

        if (dY >= (recyclerView.getHeight()
                - viewHolder.itemView.getBottom()
                - mContext.getResources().getDimensionPixelSize(R.dimen.dp_44))) {
            dragListener.deleteState(true);
            if (up) {
                //先设置不可见,如果不设置的话,会看到viewHolder返回到原位置时才消失,因为remove会在viewHolder动画执行完成后才将viewHolder删除
                viewHolder.itemView.setVisibility(View.INVISIBLE);
                adapter.getDatas().remove(viewHolder.getAdapterPosition());
                adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
                initData();
                return;
            }
        } else {//没有到删除处 , 如果viewHolder不可见,则表示用户放手,重置删除区域状态
            if (View.INVISIBLE == viewHolder.itemView.getVisibility()) {
                dragListener.dragState(false);
            }
            dragListener.deleteState(false);
        }
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    /**
     * 当长按选中item的时候(拖拽开始的时候)调用 .
     * @param viewHolder .
     * @param actionState  .
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (ItemTouchHelper.ACTION_STATE_DRAG == actionState && dragListener != null) {
            dragListener.dragState(true);
        }
        super.onSelectedChanged(viewHolder, actionState);
    }

    /**
     * 设置手指离开后ViewHolder的动画时间,在用户手指离开后调用 .
     * @param recyclerView  .
     * @param animationType .
     * @param animateDx .
     * @param animateDy .
     * @return .
     */
    @Override
    public long getAnimationDuration(RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {
        up = true;
        return super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy);
    }

    interface DragListener {
        /**
         * 用户是否将 item拖动到删除处,根据状态改变颜色
         * @param delete
         */
        void deleteState(boolean delete);

        /**
         * 是否于拖拽状态
         * @param start
         */
        void dragState(boolean start);

        /**
         * 当用户与item的交互结束并且item也完成了动画时调用
         */
        void clearView();
    }

    private DragListener dragListener;

    void setDragListener(DragListener dragListener) {
        this.dragListener = dragListener;
    }

}

 

 

 

 

 

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