RecyclerView 使用ItemTouchHelper类实现拖拽排序
程序员文章站
2022-05-15 19:30:01
...
记得以前还没有RecyclerView的时候,做拖拽排序很麻烦,而现在因为RecyclerView的诞生,很多复杂的操作都可以完美实现了,例如轮播、流式布局等等。
先写一个简单的RecyclerView例子,然后慢慢拓展吧。
public class MoveItemActivity extends AppCompatActivity {
private RecyclerView rl;
private MyAdapter adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_coo4);
initRecycler();
}
private void initRecycler() {
rl = findViewById(R.id.rv_content);
rl.setLayoutManager(new LinearLayoutManager(this));
List<String> list = new ArrayList<>();
for (int i = 0; i < 50; i++) {
list.add("这是模拟数据" + i);
}
rl.setAdapter(adapter = new MyAdapter(list));
}
public class MyAdapter extends RecyclerView.Adapter<Holder> implements ItemTouchMoveListener {
List<String> list;
public MyAdapter(List<String> list) {
this.list = list;
}
@NonNull
@Override
public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_main, parent, false);
Holder holder = new Holder(inflate);
holder.name = inflate.findViewById(R.id.tv_name);
holder.image = inflate.findViewById(R.id.iv_image);
return holder;
}
@Override
public void onBindViewHolder(@NonNull Holder holder, int position) {
holder.name.setText(list.get(position));
}
@Override
public int getItemCount() {
return list.size();
}
}
class Holder extends RecyclerView.ViewHolder {
public TextView name;
public View image;
public Holder(@NonNull View itemView) {
super(itemView);
}
}
}
运行截图:
使用v7包提供的ItemTouchHelper类处理Item的拖拽事件:
- 1.默认构造:
/**
* Creates an ItemTouchHelper that will work with the given Callback.
* <p>
* You can attach ItemTouchHelper to a RecyclerView via
* {@link #attachToRecyclerView(RecyclerView)}. Upon attaching, it will add an item decoration,
* an onItemTouchListener and a Child attach / detach listener to the RecyclerView.
*
* @param callback The Callback which controls the behavior of this touch helper.
*/
public ItemTouchHelper(Callback callback) {
mCallback = callback;
}
- 2.可以看到构造需要一个Callback,所以我们写个类进行实现:
public class ItemTouchCallback extends ItemTouchHelper.Callback {
/**
* 判断动作方向
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
int flags = makeMovementFlags(dragFlags, swipeFlags);
return flags;
}
/**
* 拖拽回调
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
if (viewHolder.getItemViewType() != target.getItemViewType()) {
return false;
}
return true;
}
/**
* 侧滑回调
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
/**
* 长按拖拽开关
*
* @return 代表是否开启长按拖拽
*/
@Override
public boolean isLongPressDragEnabled() {
return true;
}
}
- 3.将监听与RecyclerView进行绑定:
new ItemTouchHelper(new ItemTouchCallback()).attachToRecyclerView(rl);
- 4.此时RecyclerView已经可以拖动排序了,但是这里还有一个坑,UI因为拖动改变了顺序,而我们真实的数据还是原来的顺序,所以我们还需要在onMove方法中写一个监听,或者将adapter的数据传到ItemTouchCallback类,进行位置交换操作,例如:
/**
* 拖拽回调
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
if (viewHolder.getItemViewType() != target.getItemViewType()) {
return false;
}
//将我们的真实(List)数据位置交换
moveListener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
gif预览:
推荐阅读
-
Android使用CardView作为RecyclerView的Item并实现拖拽和左滑删除
-
C#使用IComparer自定义List类实现排序的方法
-
使用html5元素实现拖拽交换位置,可用于排序
-
实现拖拽效果二: 使用RecyclerView + ItemTouchHelper 实现拖拽、删除,滑动删除效果
-
RecyclerView之使用ItemTouchHelper实现拖拽和滑动删除
-
RecyclerView 使用ItemTouchHelper类实现拖拽排序
-
RecyclerView高级使用(二)-垂直拖拽排序的简单实现
-
使用h5实现react拖拽排序组件的方法(附代码)
-
使用h5实现react拖拽排序组件的方法(附代码)
-
实现拖拽效果二: 使用RecyclerView + ItemTouchHelper 实现拖拽、删除,滑动删除效果