荐 RecyclerView长按拖拽排序 ,缩短长按响应时间,长按0.1秒就可以开始拖动
程序员文章站
2022-03-11 08:27:10
RecyclerView长按拖拽排序 ,缩短长按响应时间,长按0.1秒就可以开始拖动度娘搜索RecyclerView长按拖拽排序,很多文章讲解,没找到缩短长按响应时间的,所以自己研究了一下先看效果图上代码(核心代码 重写itemtouchhelper)代码有注释,有问题可以评论回复,尽量及时答复最后上源码地址[ ItemTouchHelper 缩短长按响应时间](https://github.com/Android-xiaoxian/ItemTouchHelper)度娘搜索RecyclerView长按拖拽...
RecyclerView长按拖拽排序 ,缩短长按响应时间,长按0.1秒就可以开始拖动
度娘搜索RecyclerView长按拖拽排序,很多文章讲解,没找到缩短长按响应时间的,所以自己研究了一下
本文借鉴其他博客实现基本的拖拽排序功能,修改长按响应时间是自己实现的,转载请注明原文链接
先看效果图
上代码(核心代码 重写itemtouchhelper)
代码有注释,有问题可以评论回复,尽量及时答复
package com.example.itemtouchhelper;
import android.app.Service;
import android.graphics.Color;
import android.os.Handler;
import android.os.Vibrator;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.Collections;
import java.util.List;
/**
* @author FANG SHIXIAN
* @date 2020/6/23.
* description:
*/
public class MyItemTouchHelper {
/**
* 已选图片拖动改变顺序,
* 禁止添加图片的item拖拽,
* 拖拽到添加图片的位置不响应位置交换
*/
public static <T> void initItemTouchHelper(final RecyclerView recycler, final RecyclerView.Adapter adapter, final List<T> list) {
ItemTouchHelper helper;
ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
//某个类型的viewHolder不可拖动
// if (viewHolder instanceof XXViewHolder){ // XXViewHolder 是不可拖动的viewHolder类型,使用的时候替换
// return makeMovementFlags(0,0);
// }
int dragFlag = 0;
if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
//GridLayout布局允许 上下左右 拖动
dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
} else if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
//LinearLayout布局 只允许 上下 拖动
dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
}
//dier个参数swipeFlags应该是拖动删除
return makeMovementFlags(dragFlag, 0);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//滑动事件 下面注释的代码,滑动后数据和条目错乱,被舍弃
// Collections.swap(datas,viewHolder.getAdapterPosition(),target.getAdapterPosition());
// ap.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
//得到当拖拽的viewHolder的Position
int fromPosition = viewHolder.getAdapterPosition();
//拿到当前拖拽到的item的viewHolder
int toPosition = target.getAdapterPosition();
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(list, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(list, i, i - 1);
}
}
adapter.notifyItemMoved(fromPosition, toPosition);
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//侧滑删除可以使用;
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
/**
* 长按选中Item的时候开始调用
* 长按高亮
* @param viewHolder
* @param actionState
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
viewHolder.itemView.setBackgroundColor(Color.RED);//(拖动开始 修改item的背景色,我这里设置了红色)
//获取系统震动服务//震动70毫秒 (需要添加震动权限)
Vibrator vib = (Vibrator) recycler.getContext().getSystemService(Service.VIBRATOR_SERVICE);
vib.vibrate(70);
}
super.onSelectedChanged(viewHolder, actionState);
}
/**
* 手指松开的时候还原高亮
* @param recyclerView
* @param viewHolder
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setBackgroundColor(Color.BLUE);//(拖动结束后恢复item的背景色,我这里故意设置了蓝色)
// adapter.notifyDataSetChanged(); //完成拖动后刷新适配器,这样拖动后删除就不会错乱(拖动排序不是必须的)
}
};
helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(recycler);//ItemTouchHelper绑定recyclerView
// ItemTouchHelperGestureListener原生不是public修饰的,需要把源码复制到项目里才能实例化
ItemTouchHelper.ItemTouchHelperGestureListener listener = helper.getmItemTouchHelperGestureListener();
//Handler最后是全局使用同一个,避免内存泄漏,
// 我这里demo为了方便直接new Handler()
setLongClickDelay(new Handler(), recycler, 100, listener);
}
/**
* 修改item长按拖动的响应时间
* @param handler Handler
* @param v RecyclerView
* @param delay 长按响应时间
* @param itemTouchHelperGestureListener 修改源码后的ItemTouChHelper的itemTouchHelperGestureListener
*/
private static void setLongClickDelay(final Handler handler, final RecyclerView v, long delay,
final ItemTouchHelper.ItemTouchHelperGestureListener itemTouchHelperGestureListener) {
final long delayMillis = delay < 50 ? 50 : delay;
v.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
private static final int TOUCH_MAX = 50;
MotionEvent mEvent;
private int mLastMotionX;
private int mLastMotionY;
private boolean mHasPerformedLongPress = false;
private Runnable performLongClick = new Runnable() {
@Override
public void run() {
// mHasPerformedLongPress = v.performLongClick();
if (mEvent != null) {
mHasPerformedLongPress = true;
//响应长按onLongPress
itemTouchHelperGestureListener.onLongPress(mEvent);
mEvent = null;
}
}
};
@Override
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
mEvent = null;
handler.removeCallbacks(performLongClick);
// case 1
v.setTag(mHasPerformedLongPress);
v.performClick();
// case 2
/*if (!mHasPerformedLongPress) {
v.performClick();
}*/
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(mLastMotionX - x) > TOUCH_MAX || Math.abs(mLastMotionY - y) > TOUCH_MAX) {
mEvent = null;
handler.removeCallbacks(performLongClick);
}
break;
case MotionEvent.ACTION_DOWN:
mHasPerformedLongPress = false;
handler.removeCallbacks(performLongClick);
mLastMotionX = x;
mLastMotionY = y;
// 不能直接用mEvent = event,这样赋值 mEvent 的 getX 和 getY 得到的值是相对屏幕(或者是父布局)的,
// 具体原理不清楚
mEvent = MotionEvent.obtain(event);
handler.postDelayed(performLongClick, delayMillis);
break;
case MotionEvent.ACTION_CANCEL:
handler.removeCallbacks(performLongClick);
break;
}
return false;
}
@Override
public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent event) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
// v.setOnTouchListener(new View.OnTouchListener() {
// private static final int TOUCH_MAX = 50;
//
// private int mLastMotionX;
// private int mLastMotionY;
// private boolean mHasPerformedLongPress = false;
//
// private Runnable performLongClick = new Runnable() {
// @Override
// public void run() {
// mHasPerformedLongPress = v.performLongClick();
// }
// };
//
// @Override
// public boolean onTouch(View v, MotionEvent event) {
// int x = (int) event.getX();
// int y = (int) event.getY();
//
// switch (event.getAction()) {
// case MotionEvent.ACTION_UP:
// handler.removeCallbacks(performLongClick);
// // case 1
// v.setTag(mHasPerformedLongPress);
// v.performClick();
// // case 2
// /*if (!mHasPerformedLongPress) {
// v.performClick();
// }*/
// break;
// case MotionEvent.ACTION_MOVE:
// if (Math.abs(mLastMotionX - x) > TOUCH_MAX || Math.abs(mLastMotionY - y) > TOUCH_MAX) {
// handler.removeCallbacks(performLongClick);
// }
// break;
// case MotionEvent.ACTION_DOWN:
// time = System.currentTimeMillis();
// Log.e("test", time + " ACTION_DOWN ");
//
// mHasPerformedLongPress = false;
// handler.removeCallbacks(performLongClick);
// mLastMotionX = x;
// mLastMotionY = y;
// handler.postDelayed(performLongClick, delayMillis);
// break;
// }
// return false;
// }
// });
}
}
最后上源码地址 ItemTouchHelper 缩短长按响应时间
本文地址:https://blog.csdn.net/weixin_42120514/article/details/107143325
下一篇: 计算机网络知识整理 (1)