拖放,ListView和缺少ACTION_DRAG_STARTED事件的项目视图

时间:2013-01-02 08:34:17

标签: android drag-and-drop android-listview recycle

在Android上,我使用ListView,我希望能够使用拖放功能对其项目进行重新排序。我知道有一个“拖放列表视图”的不同实现,但是我想使用自 API级别11 以来的Drag and Drop framework

它开始非常好,直到我想在拖放时滚动ListView。正如下面的示例中所写,现在,我检查我是哪个列表元素,所以如果它的位置不在ListView.getLastVisiblePosition()ListView.getFirstVisiblePosition()之间,我使用ListView.smoothScrollToPosition()来查看其他列表项。

这是第一个实现,但效果很好。

滚动时出现问题:当我处于拖放状态时,某些元素无法回复拖放事件 - DragEvent.ACTION_DRAG_ENTERED和其他元素。这是由于ListView管理其项目视图的方式:它尝试回收不再可见的项目视图。

没关系,但它有效,但有时getView()的{​​{1}}会返回一个新对象。由于它是新的,因此该对象错过了ListAdapter,因此它无法回答其他DragEvent.ACTION_DRAG_STARTED事件!

这是一个例子。在这种情况下,如果我通过长按一下列表项开始拖放,如果我拖动它,如果我在它们之上,大多数项目将具有绿色背景;但有些人没有。

是否有任何想法让他们订阅拖放事件机制,即使他们错过了DragEvent

DragEvent.ACTION_DRAG_STARTED

1 个答案:

答案 0 :(得分:7)

我没有解决这个回收问题,但我发现可能的解决方法仍然使用Drag& amp;删除框架。我们的想法是改变观点:不是在列表中的每个OnDragListener上使用View,而是可以直接在ListView上使用。

然后我的想法是在做Drag&amp ;;时找到手指在哪个项目的顶部。删除,并在ListAdapter的{​​{1}}中写入相关的显示代码。然后诀窍是找到我们所在的项目视图,以及放置的位置。

为了做到这一点,我将ListView设置为适配器创建的每个视图id位置 - ListView,所以我可以稍后使用组合View.setId()ListView.pointToPosition()

作为一个拖动侦听器示例(我提醒您,应用于ListView.findViewById()),它可能是这样的:

ListView