继承RecycleView.Adapter
其实RecycleView实现长按拖动控件并不难,只要重写 ItemTouchHelper.Callback就好,ItemTouchHelper
是实现 RecyclerView
侧滑删除和拖拽移动的工具类。
下面的代码除了ItemTouchHelper.Callback就是普通的RecycleView.Adapter实现过程。
public class ItemAdapter extends RecyclerView.Adapter{
private Context context;
private ItemTouchHelper itemTouchHelper;
public ItemAdapter(Context context) {
this.context=context;
itemTouchHelper = new ItemTouchHelper(callback);//实例化ItemTouchHelper
}
@NonNull
@Override
public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new Holder(LayoutInflater.from(context).inflate(R.layout.item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull Holder holder, int position) {
String text = position+"";
holder.textView.setText(text);
}
@Override
public int getItemCount() {
return 10;
}
public ItemTouchHelper getItemTouchHelper(){
return itemTouchHelper;
}
public static class Holder extends RecyclerView.ViewHolder{
private TextView textView;
public Holder(@NonNull View itemView) {
super(itemView);
textView=itemView.findViewById(R.id.textview);
}
}
private final ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
// @Override
// public boolean isLongPressDragEnabled() {
// return true;
// }
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
//允许组件上下移动,以及向左滑动
return makeMovementFlags(ItemTouchHelper.UP|ItemTouchHelper.DOWN,ItemTouchHelper.LEFT);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
};
}
重点看实现拖拽的代码:
private final ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
// @Override
// public boolean isLongPressDragEnabled() {
// return true;
// }
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
//允许组件上下移动,以及向左滑动
return makeMovementFlags(ItemTouchHelper.UP|ItemTouchHelper.DOWN,ItemTouchHelper.LEFT);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
};
这三个方法是必须重写的
getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder)
一般可以
return makeMovementFlags(ItemTouchHelper.UP|ItemTouchHelper.DOWN,ItemTouchHelper.LEFT);
makeMovementFlags(int dragFlags, int swipeFlags)
dragFlags:可以拖动的方向 swipeFlags:可以滑动的方向
onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target)
拖拽一个item从旧位置移动到新位置时调用。
当用户侧滑删除某项时
onSwiped()
方法会被回调。
创建ItemTouchHelper.Callback实例以及ItemTouchHelper实例
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ItemAdapter itemAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycle_view);
recyclerView = findViewById(R.id.recycle_view);
itemAdapter = new ItemAdapter(this); //实例化adapter
//RecyclerView与ItemTouchHelper相互绑定
itemAdapter.getItemTouchHelper().attachToRecyclerView(recyclerView);
//设置adapter
recyclerView.setAdapter(itemAdapter);
//设置LayoutManager,不然item不会显示!!!
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
实现效果图:
左:初始图
右:滑动6过程图
我想把6拖动到9下面,但实际上松手后会恢复左图,也就是说我只实现了拖动,item的位置并不能变化。
重写
onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target)
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
return true; //有文章说返回false位置不能交换,我试了之后可以交换位置
}
调用 notifyItemMoved()
交换位置。