RecyclerView在拖动第一个项目时,它会跳到底部

时间:2016-03-17 11:02:20

标签: android scroll android-recyclerview drag

我正在使用“拖放”使用ItemTouchHelper在RecyclerView中删除“和”滑动到关闭“。根据这个tutorial,没有任何库。它完美地运作。 但是当RecyclerView中有滚动时会出现问题。当我开始拖动第一个项目,第一个第二个元素交换位置时,​​RecyclerView会向上滚动并且第一个元素(我正在拖动) )发生在最后一个元素之前的底部(由于RecyclerView滚动导致许多滑动发生)。它发生得非常快,所以我不能把第一个元素放在我想要的任何地方。

请注意,只有第一个元素才会发生,也只有在向下拖动时才会发生。

我认为这是因为当第二元素转到第1位时,第三元素转到第二位置并且还使用进行滑动第一个元素,与其他元素相同,它们都使用第一个元素进行滑动。我该如何解决这个问题。

当第一个项目用第二个项目更改位置时(以及项目交换位置时的任何拖动),这是调用的内容。一次交换后,一件商品就完成了:

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(categories, i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(categories, i, i - 1);
            }
        }

        notifyItemMoved(fromPosition, toPosition);
    }

2 个答案:

答案 0 :(得分:0)

该教程存在相同的问题。我搜索了这个问题,并最终在此link中得到了答案。对我来说,第二个答案非常有效。我将在链接上上传仅连接教程代码和第二个答案代码的代码。

在适配器中

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(categories, i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(categories, i, i - 1);
            }
        }

        // AdapterInteractionListener
        mListener.maintainRecyclerViewPosition(fromPosition, toPosition);
    }

在活动/片段中

    LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
    int firstPos = layoutManager.findFirstCompletelyVisibleItemPosition();
    int offsetTop = 0;
    if(firstPos >= 0){
      View firstView = layoutManager.findViewByPosition(firstPos);
      offsetTop = layoutManager.getDecoratedTop(firstView) - layoutManager.getTopDecorationHeight(firstView);
    }

    mItemAdapter.notifyItemMoved(fromPosition, toPosition);
    if(firstPos >= 0) {
      layoutManager.scrollToPositionWithOffset(firstPos, offsetTop);
    }

答案 1 :(得分:0)

只需在回调中返回true:

private val itemTouchHelper = object : ItemTouchHelper.Callback() {
        override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
            val drag = ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.START or ItemTouchHelper.END
            val swipe = 0
            return makeMovementFlags(drag, swipe)
        }

        override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
            val fromPosition = viewHolder.adapterPosition
            val toPosition = target.adapterPosition

            Collections.swap(systemsAdapter?.currentSystems, fromPosition, toPosition)
            recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)

            return true
        }

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}

        override fun isItemViewSwipeEnabled(): Boolean {
            return true
        }

        override fun isLongPressDragEnabled(): Boolean {
            return true
        }

    }