【问题标题】:Hover event in RecyclerView using ItemTouchHelper使用 ItemTouchHelper 在 RecyclerView 中的悬停事件
【发布时间】:2018-06-03 05:26:07
【问题描述】:

我有一个RecyclerView,并使用ItemTouchHelperItemTouchHelper.Callback 实现了拖放功能。

ItemTouchHelper.Callback 中,我有回调方法onMove(),它在被拖动的视图被拖到目标视图上并完成交换后被调用。

我试图实现(或查找)的是一个新的回调,当拖动的视图位于目标视图上方时,在进行交换之前调用该回调。正如您在下面的 GIF 中看到的那样。

有什么想法可以实现吗? 谢谢!

【问题讨论】:

  • LayoutManager 负责视图位置。深入挖掘与 ItemAnimator 相关的 LinearLayoutManager... 创建 RecyclerView 的人有一个很棒的视频youtube.com/watch?v=LqBlYJTfLP4
  • 你看过这个example 吗?
  • @elgringo 是的,这就是我为拖放实现所遵循的教程。
  • 我能知道你在交换之前得到那个东西的目的吗
  • @ABDevelopers 我想拖放项目以创建文件夹。在我移动项目之前,我需要显示在移动之前会发生什么的预览,并且应该在拖动的视图在目标视图上方但在移动之前显示预览。

标签: java android android-recyclerview material-design itemtouchhelper


【解决方案1】:

我找到了我提出的问题的解决方案,所以我将在此处发布。

ItemTouchHelper.Callback 有一个名为choseDropTarget() 的方法,它从被拖动视图下的ViewHolders 列表中选择一个放置目标,并在拖动视图时多次调用它。 在这里,我们有信息可以计算拖动的视图何时悬停在下面的视图以及悬停何时停止。

@Override
public RecyclerView.ViewHolder chooseDropTarget(RecyclerView.ViewHolder selected, List<RecyclerView.ViewHolder> dropTargets, int curX, int curY) {
    for (RecyclerView.ViewHolder target : dropTargets) {
            int top = curY - selected.itemView.getTop();
            int bottom = curY + selected.itemView.getHeight();
            int diff;
            if (top < 0) {
                diff = target.itemView.getTop() - curY;
            } else {
                diff = target.itemView.getBottom() - bottom;
            }
            if (Math.abs(diff) <= 100) {
                adapter.onItemHover();
            } else {
                adapter.onItemHoverFinish();
            }
    }
    return super.chooseDropTarget(selected, dropTargets, curX, curY);
}

该方法计算被拖动视图和底部视图之间的偏移差,如果差小于100,则调用onItemHover()回调,否则调用onItemHoverFinished()

如果您对此问题有更优雅的方法,请告诉我。谢谢!

【讨论】:

    【解决方案2】:

    在交换之前,您可以在此处放置对话或条件,成功后您可以交换位置。

    @Override
    public boolean onItemMove(int fromPosition, int toPosition) {
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(mItems, i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(mItems, i, i - 1);
            }
        }
        notifyItemMoved(fromPosition, toPosition);
        return true;
    }
    

    我还没有测试过,但希望这会有所帮助

    【讨论】:

    • 不幸的是,onItemMove 只有在被拖动的项目被拖动到下面的项目之外时才会被调用。当拖动的项目正好位于下面项目的顶部时,我需要显示预览,就像我附加的 GIF 一样。来自ItemTouchHelper.CallbackonMoveonMoved 回调方法也是如此。
    • 但是当它被拖到另一个项目上时。我认为它会起作用。因为即使在放入文件夹时,您也不需要在该文件夹上精确地制作项目。只需将鼠标悬停在里面就可以了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2011-08-24
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 2016-05-22
    相关资源
    最近更新 更多