RecyclerView拖放像 - FILE&夹

时间:2017-11-22 09:37:54

标签: java android android-recyclerview drag-and-drop

现在我正在使用RecyclerView的ItemTouchHelper.Callback来重新安排我的回收站视图项目的位置。

但现在我需要的是文件和文件夹的功能。

方案是文件和文件夹都是同一个回收站视图的项目。现在,当我将一个项目拖到一个文件夹上时,该文件夹不应该从它的位置移动而应该接受源视图持有者作为其自身的子项。在通过它发布项目时,源视图持有者将被隐藏并从回收站视图中删除。文件夹仍然存在。

我搜索了很多,但是无法为Recycler View找到这种行为的单一实现。

如果有人指导我应该处理什么,以获得此功能。

感谢。

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

使用ItemTouchHelper.SimpleCallback。它扩展ItemTouchHelper.Callback,因此您可以用相同的方式将它附加到RecyclerView。

您可以使用ItemTouchHelper.SimpleCallback提供的项目拖动的默认功能。 您还可以获得一些通知,以便您实现放入文件夹。

以下课程将演示如何更改文件夹的背景颜色。项目将被删除到该文件夹​​中。

您应该在所描述的位置添加用于重新排序和删除项目的代码(例如在db中)。

class ItemDragAndDropCallback extends ItemTouchHelper.SimpleCallback {

    private final RecyclerView recyclerView;

    ItemDragAndDropCallback(RecyclerView recyclerView) {
        // Choose drag and swipe directions
        // Up and down is chosen for dragging
        // Nothing is chosen for swiping
        super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0);
        this.recyclerView = recyclerView;
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        int from = viewHolder.getAdapterPosition();
        int to = target.getAdapterPosition();
        // You can reorder items here
        // Reorder items only when target is not a folder
        recyclerView.getAdapter().notifyItemMoved(from, to);
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        // You can react for swiping items here
        // Do nothing in your case
    }

    // An item will be dropped into this folder
    private View folder;

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

        if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {

            // Here you are notified that the drag operation began

            if (folder != null) {
                folder.setBackgroundResource(0); // Clear former folder background
                folder = null;
            }
        } else if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) {

            // Here you are notified that the last operation ended

            if (folder != null) {
                // Set folder background to a color indicating
                // that an item was dropped into it
                folder.setBackgroundColor(
                    ContextCompat.getColor(
                        recyclerView.getContext(), android.R.color.holo_green_dark
                    )
                );
                // You can remove item from the list here and add it to the folder
                // Remember to notify RecyclerView about it
                recyclerView.getAdapter().notifyItemRemoved(viewHolder.getAdapterPosition());
            }
        }
    }

    // This method gets called a lot, so don't do any expensive operations here
    @Override
    public void onChildDraw(
        Canvas c,
        RecyclerView recyclerView,
        RecyclerView.ViewHolder viewHolder,
        float dX,
        float dY,
        int actionState,
        boolean isCurrentlyActive
    ) {
        if (actionState == ItemTouchHelper.ACTION_STATE_DRAG && isCurrentlyActive) {

            // Here you are notified that the drag operation is in progress

            if (folder != null) {
                folder.setBackgroundResource(0); // Clear former folder background
                folder = null;
            }

            float itemActualPosition = viewHolder.itemView.getTop() + dY + viewHolder.itemView.getHeight() / 2;

            // Find folder under dragged item
            for (int i = 0; i < recyclerView.getChildCount(); i++) {
                View child = recyclerView.getChildAt(i);

                // Exclude dragged item from detection
                if (!child.equals(viewHolder.itemView)) {

                    // Accept folder which encloses item position
                    if (child.getTop() < itemActualPosition && itemActualPosition < child.getBottom()) {

                        folder = child;
                        // Set folder background to a color indicating
                        // that an item will be dropped into it upon release
                        folder.setBackgroundColor(
                            ContextCompat.getColor(
                                recyclerView.getContext(), android.R.color.holo_green_light
                            )
                        );
                        break;
                    }
                }
            }
        }
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }
}

将项目拖到文件夹上时,该项目下的文件夹背景将显示为浅绿色。 将项目放入文件夹时,其背景将为深绿色。