我想在我的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);发布于 2020-10-06 14:49:40
我忘了两件事:
**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()中所做的那样。
由itemTouchHelper.startDrag(viewHolderElement)**:** 2.触发器拖动
为此,我在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;
}
});我确信,有更有效的实现,一旦有人在这里发布一个,我将接受它。然而,这至少使它对我有用。
发布于 2020-10-06 22:05:50
我列出了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
创建一个扩展customItemTouchHelper ()的ItemTouchHelper.Callback类,您需要覆盖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)
}发布于 2020-10-06 09:33:45
对不起,我没有足够的声誉在这个问题上发表评论。尝试将return false更改为return true
https://stackoverflow.com/questions/64222981
复制相似问题