首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未触发ItemTouchHelper.SimpleCallback onMove()

未触发ItemTouchHelper.SimpleCallback onMove()
EN

Stack Overflow用户
提问于 2020-10-06 09:27:55
回答 4查看 3.5K关注 0票数 3

我想在我的RecyclerView中实现拖放。正如我所发现的,实现这一点的最佳方法是将ItemTouchHelper附加到RecyclerView

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

我就是这样做的:

代码语言:javascript
复制
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);
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-10-06 14:49:40

我忘了两件事:

**1.更新SimpleCallback如下:

代码语言:javascript
复制
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()中所做的那样。

itemTouchHelper.startDrag(viewHolderElement)**:** 2.触发器拖动

为此,我在RecyclerViewAdapter中创建了一个小接口:

代码语言:javascript
复制
public interface OnStartDragListener {
        void onStartDrag(RecyclerView.ViewHolder holder);
    }

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

代码语言:javascript
复制
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),在视图中设置如下按钮:

代码语言:javascript
复制
holder.itemBinding.dragBtn.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    mOnStartDragListener.onStartDrag(holder);
                    return false;
                }
            });

我确信,有更有效的实现,一旦有人在这里发布一个,我将接受它。然而,这至少使它对我有用。

票数 2
EN

Stack Overflow用户

发布于 2020-10-06 22:05:50

我列出了ItemTouchHelper.SimpleCallback和ItemTouchHelper.Callback()的代码。注释列在代码中,以帮助分析所发生的事情。

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

代码语言:javascript
复制
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

创建一个扩展customItemTouchHelper ()的ItemTouchHelper.Callback类,您需要覆盖getMovementFlags()、onMove()和onSwiped()

代码语言:javascript
复制
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附加到它。

代码语言:javascript
复制
val rv = findViewById<RecyclerView>(R.id.recycler_view)
    rv.apply {
        ...
        val customItemTouchHelper = ItemTouchHelper(CustomItemTouchHelper(context, viewModel))
        customItemTouchHelper.attachToRecyclerView(rv)

        }
票数 1
EN

Stack Overflow用户

发布于 2020-10-06 09:33:45

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64222981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档