使用GridLayoutManager拖放RecyclerView中的项目

编程入门 行业动态 更新时间:2024-10-27 16:33:26
本文介绍了使用GridLayoutManager拖放RecyclerView中的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

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

What I want to achieve: Have a RecyclerView with GridLayoutManager that supports drag'n'drop and that rearranges the items while dragging.

:首先使用拖放功能开发任何东西。

Side note: First time developing anything with drag and drop.

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

There are a lot of topics on how to achieve this feature using a ListView, for example: raw.githubusercontent/btownrippleman/FurthestProgress/master/FurthestProgress/src/com/anappforthat/android/languagelineup/DynamicListView.java

然而,这些示例通常是很多代码,创建了拖动视图的位图,觉得应该可以使用 View.startDrag(...)和RecyclerView与 notifyItemAdded(), notifyItemMoved()和 notifyItemRemoved() sin他们提供重新排列的动画。

However the examples are usually a lot of code with, creating bitmaps of the dragged view and it feels like it should be possible to achieve the same result using View.startDrag(...) and RecyclerView with notifyItemAdded(), notifyItemMoved() and notifyItemRemoved() since they provide rearrange animations.

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

So I played around some and came up with this:

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的或如果正确的解决方法仍然是一样的多年来一直用于ListView?

This piece of code sort of work, I get the swapping, but very unstable/shaky and sometimes when it's refreshing the whole grid is rearranged back to original order or to something random. Anyway the code above is just my first quick attempt, what I'm really more interested in knowing is if there's some standard/best practice way of doing the drag and drop with ReyclerView's or if the correct way of solving it is still the same that's been used for ListViews for years?

推荐答案

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

There is actually a better way to achieve this. You can use some of the RecyclerView's "companion" classes:

ItemTouchHelper ,这是

添加滑动关闭并拖动的实用程序类删除对RecyclerView的支持。

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

及其 ItemTouchHelper.Callback ,这是

ItemTouchHelper与您的应用程序之间的合同

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); } };

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

For more details check their documentation.

更多推荐

使用GridLayoutManager拖放RecyclerView中的项目

本文发布于:2023-10-08 08:46:57,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1472113.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:拖放   项目   GridLayoutManager   RecyclerView

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!