未触发ItemTouchHelper.SimpleCallback onMove

如何解决未触发ItemTouchHelper.SimpleCallback onMove

我想实现拖放到RecyclerView中。我发现,实现此目标的最佳方法是将itemtouchhelper附加到RecyclerView

onSwiped()工作正常,但从未触发onMove()

这就是我要做的:

EditIngredientsRecyclerViewAdapter premixableIngredientsAdapter = new EditIngredientsRecyclerViewAdapter(this,typeOfComponents);
        GridLayoutManager gridLayoutManager1 = new GridLayoutManager(getContext(),1);
        recyclerView.setAdapter(premixableIngredientsAdapter);
        recyclerView.setLayoutManager(gridLayoutManager1);

        itemtouchhelper.SimpleCallback simpleItemTouchCallback = new itemtouchhelper.SimpleCallback(0,itemtouchhelper.LEFT) {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView,@NonNull RecyclerView.ViewHolder viewHolder,@NonNull RecyclerView.ViewHolder target) {
                Log.d(TAG,"onMove: ");
                return false;
            }

            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder,int direction) {
                Log.d(TAG,"onSwiped: ");
            }
        };

        itemtouchhelper touchHelper = new itemtouchhelper(simpleItemTouchCallback);
        touchHelper.attachToRecyclerView(recyclerView);

解决方法

对不起,我没有足够的声誉在这个问题下发表评论。尝试将return false更改为return true

,

我忘了两件事:

** 1。将SimpleCallback更新为此:

ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT) {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView,@NonNull RecyclerView.ViewHolder viewHolder,@NonNull RecyclerView.ViewHolder target) {
                // Notify Adapter of the moved item!
                recyclerView.getAdapter().notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
                return true;
            }

            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder,int direction) {
                // No swipe action
            }

            @Override
            public boolean isItemViewSwipeEnabled() {
                // Disable swipe (dont override this method or return true,if you want to have swipe)
                return false;
            }

            @Override
            public int getMovementFlags(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder) {
                // Set movement flags to specify the movement direction
                // final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT;  <-- for all directions
                // In this case only up and down is allowed
                final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                final int swipeFlags = 0;
                return makeMovementFlags(dragFlags,swipeFlags);
            }
        };

尤为重要的是,像我在getMovementFlags()中所做的那样,覆盖onMove()以指定拖动方向并通知适配器已移动的物品

2。触发拖动itemTouchHelper.startDrag(viewHolderElement)

我是通过在RecyclerViewAdapter中创建一个小界面来做到这一点的:

public interface OnStartDragListener {
        void onStartDrag(RecyclerView.ViewHolder holder);
    }

创建适配器时,在新的OnStartDragListenerElement中传递,如下所示:

EditIngredientsRecyclerViewAdapter premixableIngredientsAdapter = new EditIngredientsRecyclerViewAdapter(this,typeOfComponents,new EditIngredientsRecyclerViewAdapter.OnStartDragListener() {
            @Override
            public void onStartDrag(RecyclerView.ViewHolder holder) {
                touchHelper.startDrag(holder);
                Log.d(TAG,"onStartDrag: ");
            }
        });

并在放置在视图中的按钮上的Touchlistener中调用onStartDrag(viewHolder),如下所示:

holder.itemBinding.dragBtn.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v,MotionEvent event) {
                    mOnStartDragListener.onStartDrag(holder);
                    return false;
                }
            });

我敢肯定,会有更有效的实现,一旦有人在这里发布了,我就会接受。但是,这至少使它对我有用。

,

我已经列出了ItemTouchHelper.SimpleCallback和ItemTouchHelper.Callback()的代码。代码中列出了注释,以帮助了解发生的情况。

ItemTouchHelper.SimpleCallback 在RecyclerView实现下的“活动/片段”中,创建一个ItemTouchHelper.SimpleCallback对象。您需要重写onMove()和onSwiped()方法。

ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
    ItemTouchHelper.UP or ItemTouchHelper.DOWN,ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT
) {


    // You'll need to Override
    override fun onMove(
        recyclerView: RecyclerView,viewHolder: ViewHolder,target: ViewHolder
    ): Boolean {
        // Get the position start position of the item
        val startPosition = viewHolder.adapterPosition
        // Get the endPosition,where you draged it to. 
        val endPosition = target.adapterPosition

        // Submit start and end position to notifyItemMoved. 
        recyclerView.adapter?.notifyItemMoved(startPosition,endPosition)

        // true if moved,false otherwise
        return true
    }

    override fun onSwiped ...

如果要创建CustomItemTouchCallback

创建一个扩展ItemTouchHelper.Callback()的customItemTouchHelper类,您将需要重写getMovementFlags(),onMove()和onSwiped()


class CustomItemTouchHelper(mContext: Context,val viewModel: MyViewModel) : ItemTouchHelper.Callback() {

    override fun getMovementFlags(
        recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder
    ): Int {
        val  dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
        val swipeFlags = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
        return makeMovementFlags(dragFlags,swipeFlags)
    }

    override fun onMove(
        recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder,target: RecyclerView.ViewHolder
    ): Boolean {
        val startPosition = viewHolder.adapterPosition
        val endPosition = target.adapterPosition
        
        recyclerView.adapter?.notifyItemMoved(fromPosition,toPosition)
        // true if moved,false otherwise 
        return true
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder,direction: Int) {
        val editList: MutableList<User>? = viewModel.usersList?.value as MutableList<User>?
        val editListCopy = editList?.toMutableList()
        editListCopy?.removeAt(viewHolder.adapterPosition)
        viewModel.usersList?.postValue(editListCopy)
    }

    override fun isItemViewSwipeEnabled(): Boolean {
        // Allows items to be swiped left or right.
        return true
    }

    override fun isLongPressDragEnabled(): Boolean {
        // Allows for long click so items can be dragged,moved up or down in the list. 
        return true
    }
}

现在,在“活动”或“片段”中,您需要创建一个CustomItemHelper对象,然后将RecyclerView附加到该对象。

val rv = findViewById<RecyclerView>(R.id.recycler_view)
    rv.apply {
        ...
        val customItemTouchHelper = ItemTouchHelper(CustomItemTouchHelper(context,viewModel))
        customItemTouchHelper.attachToRecyclerView(rv)

        }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?