Google已经对RecyclerView适配好了,只需调用ItemTouchHelper,重写ItemTouchHelper.Callback再与RecyclerView即可实现拖拽效果。首先新建TestItemTouchHelperCallback.java继承ItemTouchHelper.Callback,代码如下:
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
public class TestItemTouchHelperCallback extends ItemTouchHelper.Callback {
@Override
public int getMovementFlags(RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
if (recyclerView.getLayoutManager() instanceof GridLayoutManager || recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
} else {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//拖拽中的viewHolder的Position
int fromPosition = viewHolder.getAdapterPosition();
//当前拖拽到的item的viewHolder
int toPosition = target.getAdapterPosition();
if (recyclerView.getAdapter() instanceof ItemMoveCallback) {
((ItemMoveCallback) recyclerView.getAdapter()).onItemMove(fromPosition, toPosition);
}
return true;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE && viewHolder instanceof ItemHolderMoveCallback) {
((ItemHolderMoveCallback) viewHolder).onItemHolderMoveStart();
}
}
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (viewHolder instanceof ItemHolderMoveCallback) {
((ItemHolderMoveCallback) viewHolder).onItemHolderMoveEnd();
}
}
@Override
public boolean isLongPressDragEnabled() {
//返回true时自动实现长按拖拽效果
return true;
}
}
之后再初始化ItemTouchHelper并与RecyclerView绑定
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new TestItemTouchHelperCallback());
temTouchHelper.attachToRecyclerView(mRvTest);
定义了两个回调,ItemMoveCallback和ItemHolderMoveCallback,回调拖拽状态给RecyclerView适配器处理。
public interface ItemMoveCallback {
void onItemMove(int fromPosition, int toPosition);
}
public interface ItemHolderMoveCallback {
void onItemHolderMoveStart();
void onItemHolderMoveEnd();
}
RecyclerView适配器监听ItemTouchHelper的回调,自定义RecyclerView适配器代码TestAdapter如下:
package com.example.myapplication;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.Collections;
import java.util.List;
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.TestViewHolder> implements ItemMoveCallback {
private Context mContext;
private List<String> mTestList;
public TestAdapter(Context mContext, List<String> testList) {
this.mContext = mContext;
this.mTestList = testList;
}
@Override
public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new TestViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_test, null, false));
}
@Override
public void onBindViewHolder(final TestViewHolder holder, final int position) {
holder.tvTest.setText(mTestList.get(position));
}
@Override
public int getItemCount() {
return mTestList.size();
}
@Override
public void onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(mTestList, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(mTestList, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
}
static class TestViewHolder extends RecyclerView.ViewHolder implements ItemHolderMoveCallback{
private TextView tvTest;
public TestViewHolder(View itemView) {
super(itemView);
tvTest = (TextView) itemView.findViewById(R.id.tv_test);
}
@Override
public void onItemHolderMoveStart() {
tvTest.setTextSize(40);
itemView.setBackgroundColor(Color.RED);
}
@Override
public void onItemHolderMoveEnd() {
tvTest.setTextSize(32);
itemView.setBackgroundResource(R.color.colorAccent);
}
}
}
TestAdapter与RecyclerView绑定:
mRvTest.setLayoutManager(gridLayoutManager);
mTestList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
mTestList.add("测试文本" + i);
}
mTestAdapter = new TestAdapter(this, mTestList);
mRvTest.setAdapter(mTestAdapter);
布局文件中的代码:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
recyclerview依赖:
implementation'androidx.recyclerview:recyclerview-selection:1.0.0'
最终效果如下: