Android ItemTouchHelper 实践

作者: 不正经的创造者 | 来源:发表于2020-06-10 19:08 被阅读0次

    Android ItemTouchHelper 实践

    实现RecyclerView拖动排序和滑动删除,我想到的是 ViewDragHelper ,或者是第三方库,当我看了 ToDoList 的时候,发现原来官方已经支持RecyclerView拖动排序与滑动删除,那就是ItemTouchHelper。

    简介

    “ItemTouchHelper is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.

    It works with a RecyclerView and a Callback class, which configures what type of interactions are enabled and also receives events when user performs these actions.

    Depending on which functionality you support, you should override onMove(RecyclerView, ViewHolder, ViewHolder) and / or onSwiped(ViewHolder, int).”

    ItemTouchHelper 实现RecyclerView拖动排序和滑动删除,我们需要重写方法:

    int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
    

    指定可以支持的拖放和滑动的方向,上下为拖动(drag),左右为滑动(swipe)

    onMove(RecyclerView, ViewHolder, ViewHolder)
    

    滑动操作

    onSwiped(ViewHolder, int)
    

    删掉操作

    实践

    依赖

    app/build.gradle

    compile 'com.android.support:recyclerview-v7:25.0.0'
    

    效果预览

    线性

    网格


    ItemTouchHelperCallback

    新建ItemTouchHelperCallback继承ItemTouchHelper.Callback,完整代码如下:

    public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
        private ItemTouchHelperAdapter itemTouchHelperAdapter;
        private float ALPHA_FULL = 1.0f;
    
        ItemTouchHelperCallback(ItemTouchHelperAdapter itemTouchHelperAdapter) {
            this.itemTouchHelperAdapter = itemTouchHelperAdapter;
        }
    
        /**
         * RecyclerView item支持长按进入拖动操作
         */
        @Override
        public boolean isLongPressDragEnabled() {
            return true;
        }
    
        /**
         * RecyclerView item任意位置触发启用滑动操作
         */
        @Override
        public boolean isItemViewSwipeEnabled() {
            return true;
        }
    
        /**
         * 指定可以支持的拖放和滑动的方向,上下为拖动(drag),左右为滑动(swipe)
         */
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            if (recyclerView.getLayoutManager() instanceof GridLayoutManager || recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
                //不需要滑动
                final int swipeFlags = 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            } else {
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
                return makeMovementFlags(dragFlags, swipeFlags);
            }
        }
    
        /**
         * 滑动操作
         */
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            if (viewHolder.getItemViewType() != target.getItemViewType()) {
                return false;
            }
            // Notify the adapter of the move
            itemTouchHelperAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
            return true;
        }
    
        /**
         * 删掉操作
         */
        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            itemTouchHelperAdapter.onItemDismiss(viewHolder.getAdapterPosition());
        }
    
        @Override
        public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
            if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
                //自定义滑动动画
                final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
                viewHolder.itemView.setAlpha(alpha);
                viewHolder.itemView.setTranslationX(dX);
            } else {
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            }
        }
    
        @Override
        public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
            // We only want the active item to change
            if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
                if (viewHolder instanceof ItemTouchHelperViewHolder) {
                    // Let the view holder know that this item is being moved or dragged
                    ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
                    //选中状态回调
                    itemViewHolder.onItemSelected();
                }
            }
            super.onSelectedChanged(viewHolder, actionState);
        }
    
        @Override
        public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            super.clearView(recyclerView, viewHolder);
            viewHolder.itemView.setAlpha(ALPHA_FULL);
            if (viewHolder instanceof ItemTouchHelperViewHolder) {
                // Tell the view holder it's time to restore the idle state
                ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
                //未选中状态回调
                itemViewHolder.onItemClear();
            }
        }
    }
    

    attachToRecyclerView

    创建ItemTouchHelper对象,然后调用attachToRecyclerView(RecyclerView) 方法

    ItemTouchHelperCallback itemTouchHelperCallback = new ItemTouchHelperCallback(recyclerViewAdatper);
    itemTouchHelper = new ItemTouchHelper(itemTouchHelperCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);
    

    源码

    更多详见源码:github.com/WuXiaolong/… ,很多参考了iPaulPro/Android-ItemTouchHelper-Demo,关键需要消化,转化成自己的东西。

    相关文章

      网友评论

        本文标题:Android ItemTouchHelper 实践

        本文链接:https://www.haomeiwen.com/subject/jxaptktx.html