接續上一遍, 這次要講的是相對進階的操作:
效果圖:
要實現拖曳, 需要重寫onMove方法。
public ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(
    ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
    ...
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        int fromPosition = viewHolder.getBindingAdapterPosition();
        int toPosition = target.getBindingAdapterPosition();
        Collections.swap(dataList, fromPosition, toPosition); //Item互換
        notifyItemMoved(fromPosition, toPosition); //通知Recyclerview Item被移動了
        return false;
    }
    ...
}
new ItemTouchHelper.SimpleCallback(dragDirs, swipeDirs)
需要傳入兩個參數:
dragDirs:表示可以拖曳的方向swipeDirs:表示可以滑動的方向ItemTouchHelper.UP
ItemTouchHelper.DOWN
ItemTouchHelper.LEFT
ItemTouchHelper.RIGHT
效果圖:
要實現滑動,需要重寫onSwiped方法。
private List<String> archivedItems = new ArrayList<>(); // 用來紀錄右滑被封存的Item清單
public ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(
    ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
    ...
    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        int position = viewHolder.getBindingAdapterPosition();
        switch (direction) {
            // Item向左滑表示刪除
            case ItemTouchHelper.LEFT:
                dataList.remove(position);
                notifyItemRemoved(position); // 通知RecyclerView有Item被刪除了, 用以更新畫面
                break;
            // Item向右滑表示封存
            case ItemTouchHelper.RIGHT:
                String itemName = dataList.get(position);
                archivedItems.add(itemName);
                dataList.remove(position);
                notifyItemRemoved(position); // 通知RecyclerView有Item被刪除了, 用以更新畫面
                break;
        }
    }
}
在github上有位大神已經實現這樣的效果並提供簡單的API供使用,我們只需要把這個第三方套件導入自己的專案即可。跟著以下的步驟配置環境:
套件連結:https://github.com/xabaras/RecyclerViewSwipeDecorator
settings.gradle添加dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
build.gradle(Module: app)添加依賴dependencies {
    ...
    implementation 'com.github.xabaras:RecyclerViewSwipeDecorator:1.4'
}
onChildDraw來實現在滑動時, item後面呈現圖示的效果public ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(
    ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
    ...
    @Override
    public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        new RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
            .addSwipeLeftBackgroundColor(ContextCompat.getColor(viewHolder.itemView.getContext(), R.color.item_delete))
            .addSwipeLeftActionIcon(R.drawable.ic_delete_24dp)
            .addSwipeRightBackgroundColor(ContextCompat.getColor(viewHolder.itemView.getContext(), R.color.item_archive))
            .addSwipeRightActionIcon(R.drawable.ic_archive_24dp)
            .create()
            .decorate();
        
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }
}
private String deletedItem = null; // 用來記錄左滑刪除的Item
private List<String> archivedItems = new ArrayList<>(); // 用來紀錄右滑被封存的Item清單
public ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(
    ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
    ...
        
    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        int position = viewHolder.getBindingAdapterPosition(); // 紀錄當前滑動的item位置
        switch (direction) {
            // Item向左滑表示刪除
            case ItemTouchHelper.LEFT:
                deletedItem = dataList.get(position);
                dataList.remove(position);
                notifyItemRemoved(position);
                // 復原操作提示
                Snackbar.make(viewHolder.itemView, deletedItem + " 已被刪除", Snackbar.LENGTH_LONG)
                        .setAction("復原", (view) -> {
                                    dataList.add(position, deletedItem);
                                    notifyItemInserted(position);
                                }
                        ).show();
                break;
            // Item向右滑表示封存
            case ItemTouchHelper.RIGHT:
                String itemName = dataList.get(position);
                archivedItems.add(itemName);
                dataList.remove(position);
                notifyItemRemoved(position);
                // 復原操作提示
                Snackbar.make(viewHolder.itemView, itemName + " 已被封存", Snackbar.LENGTH_LONG)
                        .setAction("復原", (view) -> {
                                    dataList.add(position, itemName);
                                    archivedItems.remove(archivedItems.indexOf(itemName));
                                    notifyItemInserted(position);
                                }
                        ).show();
                break;
        }
    }
    ...
}