Android ItemTouchHelper 實踐

實現RecyclerView拖動排序和滑動刪除,我想到的是 ViewDragHelper ,或者是第三方庫,當我看了 ToDoList 的時候,發現原來官方已經支持RecyclerView拖動排序與滑動刪除,那就是ItemTouchHelper。html

簡介

「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.java

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

ItemTouchHelper 實現RecyclerView拖動排序和滑動刪除,咱們須要重寫方法:git

int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)複製代碼

指定能夠支持的拖放和滑動的方向,上下爲拖動(drag),左右爲滑動(swipe)github

onMove(RecyclerView, ViewHolder, ViewHolder)複製代碼

滑動操做微信

onSwiped(ViewHolder, int)複製代碼

刪掉操做app

實踐

依賴

app/build.gradleide

compile 'com.android.support:recyclerview-v7:25.0.0'複製代碼

效果預覽

線性
gradle


網格

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,關鍵須要消化,轉化成本身的東西。

參考

官網Api
Drag and Swipe with RecyclerView
Drag and Swipe with RecyclerView—Part Two

聯繫我

個人微信公衆號:吳小龍同窗,歡迎關注交流~

QQ羣

相關文章
相關標籤/搜索