RecyclerView 拖放喜欢 - 文件和文件夹
Posted
技术标签:
【中文标题】RecyclerView 拖放喜欢 - 文件和文件夹【英文标题】:RecyclerView Drag and Drop like - FILE & FOLDER 【发布时间】:2018-05-05 23:36:10 【问题描述】:现在我正在使用 RecyclerView 的 ItemTouchHelper.Callback 来重新排列回收站视图中项目的位置。
但现在我需要的是文件和文件夹的功能。
场景是文件和文件夹都是同一个回收站视图的项目。现在,当我将一个项目拖到一个文件夹上时,该文件夹不应从其位置移动,而是应接受源视图持有者作为其自身的子级。并且在它上面释放一个项目时,源视图持有者被隐藏并从回收者视图中删除。虽然文件夹仍然存在。
我在 Google 上搜索了很多,但无法为 Recycler View 找到此类行为的单一实现。
如果有人指导我应该处理什么,以获得此功能。
谢谢。
【问题讨论】:
你找到解决方案了吗?我需要像你这样的类似功能。找不到任何东西。 【参考方案1】:使用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);
当您将项目拖到文件夹上时,项目下的文件夹背景将变为浅绿色。 当您将项目放入文件夹时,其背景将变为深绿色。
【讨论】:
我没有在“onSelectedChanged: 方法中访问recyclerView。我怎样才能得到recyclerView? 你必须将它作为构造函数参数传递。以上是关于RecyclerView 拖放喜欢 - 文件和文件夹的主要内容,如果未能解决你的问题,请参考以下文章
在ANDROID中相互拖放时合并Recyclerview中的项目?