gpt4 book ai didi

android - 使用 GridLayoutManager 在 RecyclerView 中拖放项目

转载 作者:IT王子 更新时间:2023-10-29 00:00:47 25 4
gpt4 key购买 nike

我想要实现的目标:有一个带有 GridLayoutManager 的 RecyclerView,它支持拖放并在拖动时重新排列项目。

旁注:第一次使用拖放开发任何东西。

关于如何使用 ListView 实现此功能的主题很多,例如:https://raw.githubusercontent.com/btownrippleman/FurthestProgress/master/FurthestProgress/src/com/anappforthat/android/languagelineup/DynamicListView.java

但是,示例通常包含大量代码,用于创建拖动 View 的位图,感觉应该可以使用 View.startDrag(...) 和RecyclerView 带有 notifyItemAdded()notifyItemMoved()notifyItemRemoved(),因为它们提供重新排列动画。

所以我玩了一些并想出了这个:

final CardAdapter adapter = new CardAdapter(list);
adapter.setHasStableIds(true);
adapter.setListener(new CardAdapter.OnLongClickListener() {
@Override
public void onLongClick(View view) {
ClipData data = ClipData.newPlainText("","");
View.DragShadowBuilder builder = new View.DragShadowBuilder(view);
final int pos = mRecyclerView.getChildAdapterPosition(view);
final Goal item = list.remove(pos);

mRecyclerView.setOnDragListener(new View.OnDragListener() {
int prevPos = pos;

@Override
public boolean onDrag(View view, DragEvent dragEvent) {
final int action = dragEvent.getAction();
switch(action) {
case DragEvent.ACTION_DRAG_LOCATION:
View onTopOf = mRecyclerView.findChildViewUnder(dragEvent.getX(), dragEvent.getY());
int i = mRecyclerView.getChildAdapterPosition(onTopOf);

list.add(i, list.remove(prevPos));
adapter.notifyItemMoved(prevPos, i);
prevPos = i;
break;

case DragEvent.ACTION_DROP:
View underView = mRecyclerView.findChildViewUnder(dragEvent.getX(), dragEvent.getY());
int underPos = mRecyclerView.getChildAdapterPosition(underView);

list.add(underPos, item);
adapter.notifyItemInserted(underPos);
adapter.notifyDataSetChanged();
break;
}

return true;
}
});

view.startDrag(data, builder, view, 0);
}
});
mRecyclerView.setAdapter(adapter);

这段代码有点工作,我得到了交换,但非常不稳定/不稳定,有时当它刷新时,整个网格会重新排列回原始顺序或随机的东西。无论如何,上面的代码只是我的第一次快速尝试,我真正更感兴趣的是是否有一些标准/最佳实践方法可以使用 ReyclerView 进行拖放,或者解决它的正确方法是否仍然相同多年来一直用于 ListViews?

最佳答案

实际上有更好的方法来实现这一点。您可以使用一些 RecyclerView 的“companion”类:

ItemTouchHelper ,即

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

及其ItemTouchHelper.Callback ,即

the contract between ItemTouchHelper and your application

// Create an `ItemTouchHelper` and attach it to the `RecyclerView`
ItemTouchHelper ith = new ItemTouchHelper(_ithCallback);
ith.attachToRecyclerView(rv);

// Extend the Callback class
ItemTouchHelper.Callback _ithCallback = new ItemTouchHelper.Callback() {
//and in your imlpementaion of
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// get the viewHolder's and target's positions in your adapter data, swap them
Collections.swap(/*RecyclerView.Adapter's data collection*/, viewHolder.getAdapterPosition(), target.getAdapterPosition());
// and notify the adapter that its dataset has changed
_adapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//TODO
}

//defines the enabled move directions in each state (idle, swiping, dragging).
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return makeFlag(ItemTouchHelper.ACTION_STATE_DRAG,
ItemTouchHelper.DOWN | ItemTouchHelper.UP | ItemTouchHelper.START | ItemTouchHelper.END);
}
};

有关更多详细信息,请查看他们的文档。

关于android - 使用 GridLayoutManager 在 RecyclerView 中拖放项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29901044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com