之前一直觉得列表的拖拽换位和侧滑删除是很难实现的,不过之后参考了下几篇博客后发,发现还是很简单的,因为suppor早就封装好了,最主要的是继承ItemTouchHelper.Callback,并对其方法
效果图如下:
步骤如下:
1、新建类并继承ItemTouchHelper.Callback,在其对应方法设置相应操作包括,不同布局的拖拽和侧滑删除,选择效果
2、Adapter中实现自定义的监听回调,对位置交换和删除动作做对应的数据操作和界面的刷新
3、主代码中 新建ItemTouchHelper 并关联RecyclerView即可
代码如下:
1、新建类并继承ItemTouchHelper.Callback,在其对应方法设置相应操作
public interface ItemTouchHelperAdapter {
//数据交换
void onItemMove(int fromPosition,int toPosition);
//数据删除
void onSwiped(int position);
}
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
private ItemTouchHelperAdapter mAdapter;
private boolean dragEnabled; //能否拖拽
private boolean swipeEnabled; //能否侧滑
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter, boolean dragEnabled, boolean swipeEnabled) {
mAdapter = adapter;
this.dragEnabled = dragEnabled;
this.swipeEnabled = swipeEnabled;
}
//同来设置 拖拽移动,或移动删除
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {// GridLayoutManager
// flag如果值是0,相当于这个功能被关闭
int dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlag = 0;
// create make
return makeMovementFlags(dragFlag, swipeFlag);
} else if (layoutManager instanceof LinearLayoutManager) {// linearLayoutManager
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
int orientation = linearLayoutManager.getOrientation();
int dragFlag = 0;
int swipeFlag = 0;
// 为了方便理解,相当于分为横着的ListView和竖着的ListView
if (orientation == LinearLayoutManager.HORIZONTAL) {// 如果是横向的布局
swipeFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
} else if (orientation == LinearLayoutManager.VERTICAL) {// 如果是竖向的布局,相当于ListView
dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
}
return makeMovementFlags(dragFlag, swipeFlag);
}
return 0;
}
//是否能拖动
@Override
public boolean isLongPressDragEnabled() {
return dragEnabled;
}
//是否能侧滑
@Override
public boolean isItemViewSwipeEnabled() {
return swipeEnabled;
}
//拖动
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
Log.e(TAG, "onMove");
// if (viewHolder.getAdapterPosition() == 0) {
//第一个无法拖拽
// return false;
// }
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
//左右滑动
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
mAdapter.onSwiped(viewHolder.getAdapterPosition());
Log.e(TAG, "onSwiped");
}
//选中项操作
@Override
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
Log.e(TAG, "onSelectedChanged");
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
if (viewHolder != null)
viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
}
}
//释放选中项操作
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
Log.e(TAG, "clearView");
viewHolder.itemView.setBackgroundColor(0);
}
}
2、Adapter中实现自定义的监听回调
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Holder> implements ItemTouchHelperAdapter {
private Context mContext;
private List<String> mList;
public MyAdapter(Context context, List<String> list) {
mContext = context;
mList = list;
}
@NonNull
@Override
public Holder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new Holder(LayoutInflater.from(mContext).inflate(R.layout.item_test, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull final Holder holder, final int i) {
holder.tvF.setText(mList.get(i));
holder.tvS.setText(mList.get(i));
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//移除数据
mList.remove(i);
notifyDataSetChanged();
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
@Override
public void onItemMove(int fromPosition, int toPosition) {
//交换位置
Collections.swap(mList, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onSwiped(int position) {
//移除数据
mList.remove(position);
notifyItemRemoved(position);
}
static class Holder extends RecyclerView.ViewHolder {
private TextView tvF;
private TextView tvS;
private ImageView delete;
public Holder(@NonNull View itemView) {
super(itemView);
tvF = itemView.findViewById(R.id.tv_first);
tvS = itemView.findViewById(R.id.tv_second);
delete = itemView.findViewById(R.id.delete);
}
}
}
3、主代码中 新建ItemTouchHelper 并关联RecyclerView
public class MainActivity extends AppCompatActivity {
public static final String TAG = "recyclerviewmove";
private Button btnChange;
private RecyclerView mRecyclerView;
private MyAdapter mMyAdapter;
private List<String> mList = new ArrayList<>();
private boolean bGrid; //布局标识
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 0; i < 9; i++) {
mList.add(i + "" + i + "" + i);
}
mRecyclerView = findViewById(R.id.recycler_view);
btnChange = findViewById(R.id.btn_change);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mMyAdapter = new MyAdapter(this, mList);
mRecyclerView.setAdapter(mMyAdapter);
//关联ItemTouchHelper和RecyclerView
ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(mMyAdapter,true,true);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(mRecyclerView);
btnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (bGrid) {
mRecyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
} else {
mRecyclerView.setLayoutManager(new GridLayoutManager(MainActivity.this, 4));
}
bGrid = !bGrid;
}
});
}
}
参考:RecyclerView进阶:使用ItemTouchHelper实现拖拽和侧滑删除_recyclerview把item可以拖拽到任意地方具体实现_程序员的自我反思的博客-CSDN博客