当前位置: 首页 > 知识库问答 >
问题:

用GridLayoutManager拖放RecycerView中的项

向和歌
2023-03-14

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

关于如何使用ListView实现此功能,有很多主题,例如:https://raw.githubusercontent.com/btownRippleman/furthestProgress/master/furthestProgress/src/com/anappforthat/android/languagelineup/dynamicListView.java

但是,这些示例通常使用大量代码创建拖动视图的位图,并且使用view.startdrag(...)和RecyerView使用NotifyItemAddad()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多年来使用的方法相同?

共有1个答案

李法
2023-03-14

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

ItemTouchHelper,它是

一个实用程序类,用于添加swipe以解除和RecycerView的拖放支持。

// 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);
    }
};
 类似资料:
  • 我在Windows JVM 7_25中测试了此代码,它运行良好。 当我用JVM在Linux测试相同的代码时7_25我得到了这个错误堆栈: (以及更多) < code > int incoming index = integer . parse int(drag board . getstring())的内容;为空 你能告诉我如何解决这个问题或重写代码吗?

  • 我试图使用HTML5拖放在我的网站。dragstart和dragend被解雇,但dragenter,draglet,dragover和下降不工作,直到我刷新页面。 侧边栏中树中的节点应该能够拖动到表中的单元格。树是用jsTree制作的。我已经在火狐、Chrome和IE上尝试过了。他们都有相同的行为。 边栏树(rhtml文件) 删除操作代码(咖啡脚本文件) 表(页面来源) 我试着拉小提琴,但效果很好

  • 我使用jQuery来满足我的拖放需求,为什么不能在这里工作是我下面的代码,我的需求是:首先,当我将图像拖到表格单元格中时,我要启用/显示一个div;然后,我要将一个跨度拖到新显示的div中,当图像被拖动时,这个跨度就不能在启用的div中拖放了。为什么需要帮助我是jQuery的新手。 null null 因此,问题是拖动图像后,组成的div块被启用/附加在表格单元格内,之后,当我们将跨距拖动到表格单

  • 问题内容: 我正在使用TransferHandler将数据从JPanel作为JLabel传递到JTextArea (单击左侧面板中的某处以创建要拖动的JLabel) 数据的传输工作正常,但是我还想“显示” JLabel,因为 它与鼠标指针一起被拖动。 如果您注释掉 您将看到我想要它的外观。(但当然不会传输数据)。 如何既可以进行传输又可以使JLabel跟随鼠标光标? 这是代码: 问题答案: 另一个

  • 但是大多数投票解决方案的问题是,它调用的所有项,因此,例如,如果它是一个无休止的RecycerView,当用户到达列表的末尾时,您希望发出网络请求,那么使用该解决方案,会重复调用server,因为它会自动到达的最后一项。 不管怎样,如何设置参数以便我可以将放入中(实际上,我希望将像framelayout或RelationVelayout这样的viewgroup作为nestedscrollview的