失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > RecyclerView实现Item可拖拽(拖动 删除)

RecyclerView实现Item可拖拽(拖动 删除)

时间:2020-11-01 22:05:11

相关推荐

RecyclerView实现Item可拖拽(拖动 删除)

RecyclerView实现Item可拖拽(拖动、删除)

话不多说,先附上效果图:

ItemTouchHelper

这是一个RecyclerView的工具,提供了drag & swipe 的功能,可以帮助我们处理RecyclerView中的Item的拖拽和滑动事件。

ItemTouchHelper helper = new ItemTouchHelper(new MyItemTouchHelperCallback(mAdapter,this));helper.attachToRecyclerView(mRecyclerView);

ItemTouchHelper.Callback

ItemTouchHelper.Callback是一个抽象类,里面有一些抽象方法需要开发者去重写。重写方法如下:

1. getMovementFlags(RecyclerView, ViewHolder) 2. onMove(RecyclerView, ViewHolder, ViewHolder)3. onSwiped(ViewHolder, int)4. onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)5. clearView(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder)6. isLongPressDragEnabled()7. isItemViewSwipeEnabled()

getMovementFlags(RecyclerView, ViewHolder)

这个方法是设置那些方向可以拖动和滑动RecyclerView中的item

@Overridepublic int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {int dragFlag; //拖动标记int swipeFlags; //滑动标记//如果是表格布局,则可以上下左右的拖动,但是不能滑动if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {dragFlag = ItemTouchHelper.UP |ItemTouchHelper.DOWN |ItemTouchHelper.LEFT |ItemTouchHelper.RIGHT;swipeFlags = 0;}//如果是线性布局,那么只能上下拖动,只能左右滑动else {dragFlag = ItemTouchHelper.UP |ItemTouchHelper.DOWN;swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;}//通过makeMovementFlags生成最终结果return makeMovementFlags(dragFlag, swipeFlags);}

onMove(RecyclerView, ViewHolder, ViewHolder)

拖动item的回调方法,在这里面实现拖动需要做的事情,比如RecyclerView里面item的顺序交换,

传入的参数是被拖动item的ViewHolder和目标ViewHolder

@Overridepublic boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {//被拖动的item位置int fromPosition = viewHolder.getLayoutPosition();//他的目标位置int targetPosition = target.getLayoutPosition();//为了降低耦合,使用接口让Adapter去实现交换功能mItemPositionListener.onItemSwap(fromPosition, targetPosition);return true;}

onSwiped(ViewHolder, int)

滑动item的回调方法,在这里面实现滑动需要做的事情,比如RecyclerView里面item的删除

@Overridepublic void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {//为了降低耦合,使用接口让Adapter去实现交换功能mItemPositionListener.onItemMoved(viewHolder.getLayoutPosition());}

onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)

在每次item的状态变成拖拽 (ACTION_STATE_DRAG) 或者 滑动 (ACTION_STATE_SWIPE)的时候被调用。这是把你的item view变成激活状态的最佳地点。

@Overridepublic void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {super.onSelectedChanged(viewHolder, actionState);//当开始拖拽的时候if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {//修改背景颜色viewHolder.itemView.setBackgroundColor(Color.LTGRAY);//手机振动Vibrator vibrator = (Vibrator)mContext.getSystemService(mContext.VIBRATOR_SERVICE);vibrator.vibrate(50);}}

clearView(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder)

item被放开或者动画完成的回调

//当手指松开的时候@Overridepublic void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {viewHolder.itemView.setBackgroundColor(Color.TRANSPARENT);super.clearView(recyclerView, viewHolder);}

isLongPressDragEnabled()

设置是否长按才进入拖动

isItemViewSwipeEnabled()

设置是否支持滑动操作

简单Demo

开启振动权限

<uses-permission android:name="android.permission.VIBRATE"/>

public class MainActivity extends AppCompatActivity {private RecyclerView mRecyclerView;private MyAdapter mAdapter = new MyAdapter();private ItemTouchHelper helper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mRecyclerView = findViewById(R.id.mRecyclerView);GridLayoutManager mLinearLayoutManager;mLinearLayoutManager = new GridLayoutManager(this, 3);mRecyclerView.setLayoutManager(mLinearLayoutManager);mRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayout.HORIZONTAL));mRecyclerView.setAdapter(mAdapter);helper = new ItemTouchHelper(new MyItemTouchHelperCallback(mAdapter,this));helper.attachToRecyclerView(mRecyclerView);}/*** 数据默认写死的*/public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> implements OnItemPositionListener {private List<String> mDatas = new ArrayList<>();public MyAdapter() {for (int i = 0; i < 30; i++) {mDatas.add("item:" + i);}}@Overridepublic MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {return new MyHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle, parent, false));}@Overridepublic int getItemCount() {return mDatas.size();}@Overridepublic void onBindViewHolder(MyHolder holder, int position) {holder.tv.setText(mDatas.get(position));}@Overridepublic void onItemSwap(int from, int target) {// Collections.swap(mDatas, from, target);//交换数据String s = mDatas.get(from);mDatas.remove(from);mDatas.add(target,s);notifyItemMoved(from, target);}@Overridepublic void onItemMoved(int position) {mDatas.remove(position);notifyItemRemoved(position);}protected class MyHolder extends RecyclerView.ViewHolder {public TextView tv;public ImageView drag;public MyHolder(View itemView) {super(itemView);tv = itemView.findViewById(R.id.item_tv);drag = itemView.findViewById(R.id.item_drag);//drag.setOnTouchListener(this);}/*@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {helper.startDrag(this);}return false;}*/}}}

ItemTouchHelper.Callback的isLongPressDragEnabled方法,让其返回false,表示我们不需要默认的长按开始拖动功能。然后在我们需要开始拖动的地方调用ItemTouchHelper.startDrag(ViewHolder viewHolder)方法即可开始拖动

public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {private OnItemPositionListener mItemPositionListener;private Context mContext;public MyItemTouchHelperCallback(OnItemPositionListener itemPositionListener, Context context) {mItemPositionListener = itemPositionListener;mContext = context;}@Overridepublic int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {int dragFlag;int swipeFlags;//如果是表格布局,则可以上下左右的拖动,但是不能滑动if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {dragFlag = ItemTouchHelper.UP |ItemTouchHelper.DOWN |ItemTouchHelper.LEFT |ItemTouchHelper.RIGHT;swipeFlags = 0;}//如果是线性布局,那么只能上下拖动,只能左右滑动else {dragFlag = ItemTouchHelper.UP |ItemTouchHelper.DOWN;swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;}//通过makeMovementFlags生成最终结果return makeMovementFlags(dragFlag, swipeFlags);}@Overridepublic boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {//被拖动的item位置int fromPosition = viewHolder.getLayoutPosition();//他的目标位置int targetPosition = target.getLayoutPosition();//为了降低耦合,使用接口让Adapter去实现交换功能mItemPositionListener.onItemSwap(fromPosition, targetPosition);return true;}@Overridepublic void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {//为了降低耦合,使用接口让Adapter去实现交换功能mItemPositionListener.onItemMoved(viewHolder.getLayoutPosition());}@Overridepublic void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {super.onSelectedChanged(viewHolder, actionState);//当开始拖拽的时候if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {viewHolder.itemView.setBackgroundColor(Color.LTGRAY);Vibrator vibrator = (Vibrator)mContext.getSystemService(mContext.VIBRATOR_SERVICE);vibrator.vibrate(50);}}//当手指松开的时候@Overridepublic void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {viewHolder.itemView.setBackgroundColor(Color.TRANSPARENT);super.clearView(recyclerView, viewHolder);}//禁止长按滚动交换,需要滚动的时候使用{@link ItemTouchHelper#startDrag(ViewHolder)}@Overridepublic boolean isLongPressDragEnabled() {//return false;return true;}}

public interface OnItemPositionListener {//交换void onItemSwap(int from, int target);//滑动void onItemMoved(int position);}

如果觉得《RecyclerView实现Item可拖拽(拖动 删除)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。