Android - RecyclerView 拖动使用 ItemTouchHelper.Callback

Android - RecyclerView drag using ItemTouchHelper.Callback

我目前正在开发一个小型 Android 模块,我遇到了一个问题,也许有人可以解决。我需要 创建一个日历并允许用户通过以下方式 select 一个日期范围:1) 单击开始日期(这将默认创建一个 2 天的范围)然后 2) 触摸一个范围边框并拖动它以增大或减小该范围

目前,我使用 RecyclerView 和 GridLayoutManager 创建了所有日历天单元格,它有很多行(所有周),每行 7 个项目(天).然后 我使用 RecyclerView ItemTouchHelper (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.html) and ItemTouchHelper.Callback (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.Callback.html) to complete the drag&drop functionality. My approach was to use the drag&drop detection provided by those helpers (take a look at https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.ib8r012gc) 修改它以避免移动一个项目并且只检测我想要的触摸+拖放手势。我已经通过删除默认拖动动画(覆盖 ItemTouchHelper onDraw/onDrawOver)并使用 ItemTouchHelper.Callback 回调来管理拖动运动(无需交换适配器项目,因为我总是需要它们相同的位置)。一切正常,但我现在遇到了一个问题,因为拖动检测没有按预期工作。我将尝试解释它:如果我在给定单元格的中心开始拖动运动,然后移动到其左侧的单元格,则拖动运动不会被触发,直到我到达左侧单元格的中心(与我开始拖动运动的位置相同)。这是一个问题,因为我需要在到达另一个单元格后立即检测到拖动(如果手指在新单元格边界内,则应触发拖动)。另一个例子是:如果我在一个单元格的最左边开始拖动运动,直到我到达另一个单元格的最左边才会触发拖动。

现在 我正在尝试使用 ItemTouchHelper.Callback.chooseDropTarget 方法 来在手指进入后立即手动 select 放置目标一个新的单元格,但我无法让它工作。我认为(但我不能确定)接收到的 x,y 坐标有些奇怪。

我知道一些代码示例会很有帮助,但我无法粘贴它,因为它属于一个私有且受保护的存储库:(

如果有人能提供给我任何帮助,我将不胜感激。而且,当然,我会尝试暂挂此主题以提供我能提供的所有信息。我还将考虑 新的不同方法和建议来获得 "touch+move+up" 运动 我需要移动范围边界 :)

非常感谢所有 Stack Overflow 社区!

经过更多研究,我找到了解决问题的方法。我会 post 这样如果有人遇到同样的问题,他可以在这里找到一些帮助 :)

我的问题是我正在使用 ItemTouchHelper.Callback.chooseDropTarget (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.Callback.html#chooseDropTarget(android.support.v7.widget.RecyclerView.ViewHolder,%20java.util.List%3Candroid.support.v7.widget.RecyclerView.ViewHolder%3E,%20int,%20int)) 返回的 curXcurY 参数,就好像它们是拖动时的当前手指坐标一样,但它们是应用任何平移后拖动视图最左上角坐标的坐标。现在我觉得有点傻。我应该更好地阅读文档:|

因为我不需要最左上角的坐标而是手指的位置,所以我的解决方案是使用附加到源视图的触摸侦听器,这样我就可以检测到初始触摸 x、y 坐标(相对于该视图)使用 touchSrcX = MotionEvent.getX()touchSrcY = MotionEvent.getY() 方法,然后在 chooseDropTarget 回调中选择目标之前应用点转换。我的意思是,类似于: curX += touchSrcX curY += touchSrcY

如果有人需要更多详细信息或更好的解释,请与我联系,我很乐意提供帮助! :)