RecyclerView之ItemTouchHelper仿今日头条频道管理拖动

Github地址:这里写链接内容
ItemTouchHelper的使用

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                return 0;
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

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

            }

            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                super.onSelectedChanged(viewHolder, actionState);
            }

            @Override
            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                super.clearView(recyclerView, viewHolder);
            }

            @Override
            public boolean isLongPressDragEnabled() {
                return super.isLongPressDragEnabled();
            }
        });
        itemTouchHelper.attachToRecyclerView(recyclerView);

首先创建ItemTouchHelper对象,它的构造方法需要一个ItemTouchHelper.Callback,重写它的几个方法:

//dragFlags确定拖动方向,swipeFlags确定滑动删除
 @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
        int swipeFlags = 0;
        return makeMovementFlags(dragFlags,swipeFlags);
    }
//当发生拖动时候的回调方法
 @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        if(viewHolder.getItemViewType()!=target.getItemViewType()){
            return false;
        }
        if(recyclerView.getAdapter() instanceof OnItemMovedListener){
            OnItemMovedListener onItemMovedListener = (OnItemMovedListener) recyclerView.getAdapter();
            onItemMovedListener.onItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
        }
        return true;
    }
//当点击item时的回调,这里是将item放大
@Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);
        if(actionState == ItemTouchHelper.ACTION_STATE_IDLE){
            return;
        }
        viewHolder.itemView.setScaleX(1.2f);
        viewHolder.itemView.setScaleY(1.2f);
    }
//松手后的回调,这里将view还原到初始大小
@Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        viewHolder.itemView.setScaleX(1f);
        viewHolder.itemView.setScaleY(1f);
    }
//是否开启长按拖动,因为不是所有的item都支持长按拖动,这里设置为false,在之后可以调用itemTouchHelper.startDrag()开始拖动
@Override
    public boolean isLongPressDragEnabled() {
        return false;
    }

定义一个接口用来处理拖时的数据及UI变化

public interface OnItemMovedListener {
    void onItemMoved(int fromPosition,int toPosition);
}

接下来是Adapter的代码编写,
首先adapter实现OnItemMovedListener接口来处理数据交换和recyclerview的UI动效:

@Override
    public void onItemMoved(int fromPosition, int toPosition) {
        ChannelEntity channelEntity = myChannels.get(fromPosition - 1);
        myChannels.remove(fromPosition - 1);
        myChannels.add(toPosition - 1, channelEntity);
        notifyItemMoved(fromPosition, toPosition);
    }

其他重写getItemViewType、onCreateViewHolder、onBindViewHolder方法没有特别之处,不做赘述,详情见github上的代码。
接下来主要讲解一下删除已选的item和添加item的动画实现。
主要是通过view.getDrawingCache()获取点击的View的bitmap,new一个ImageView设置src为刚刚生成的bitmap,再对其进行translateAnimation.

删除item的动画实现:

@Override
                    public void onClick(View v) {
                        int position = myChannelViewHolder.getAdapterPosition();
                        RecyclerView recyclerView = (RecyclerView) parent;
                        if (isEditMode) {
                            View targetView = recyclerView.getLayoutManager().findViewByPosition(myChannels.size() + 2);
                            View currentView = recyclerView.getLayoutManager().findViewByPosition(position);
                            //如果目标targetView(indexOfChild>=0)在屏幕内,则需要添加动画效果;
                            // 如果不在屏幕内,那么recyclerview的notifyItemMoved会有向目标移动的动画
                            if (recyclerView.indexOfChild(targetView) >= 0) {
                                //目标位置的坐标
                                float targetX, targetY;
                                int spanCount = ((GridLayoutManager) (recyclerView.getLayoutManager())).getSpanCount();
                                //如果已选的item在最后一行的第一个位置,那么移动后高度会变化,所以目标View就是当前View的下一个view
                                if ((myChannels.size() - 1) % spanCount == 0) {
                                    View preTargetView = recyclerView.getLayoutManager().findViewByPosition(myChannels.size() + 1);
                                    targetX = preTargetView.getLeft();
                                    targetY = preTargetView.getTop();
                                } else {
                                    targetX = targetView.getLeft();
                                    targetY = targetView.getTop();
                                }
                                moveMineToOthers(myChannelViewHolder);
                                startAnimation((RecyclerView) parent, currentView, targetX, targetY);


                            } else {
                                moveMineToOthers(myChannelViewHolder);

                            }
                        }
                    }

未完待续

你可能感兴趣的:(RecyclerView之ItemTouchHelper仿今日头条频道管理拖动)