背景:
安卓系统有自带的setOnLongClickListener长按事件,但是系统自带的长按往往时间太短,不符合我们的需求,我们可以自定义一个view,来实现特定时间的长按时间。
实现:
public class LongClickLayout extends FrameLayout {
private final static String TAG = "LongClickLayout";
// 长按时间
private static final long DEFAULT_TIME = 3000L;
private int mLastMotionX;
private int mLastMotionY;
//是否移动了
private boolean isMoved;
//是否释放了
private boolean isReleased;
//计数器,防止多次点击导致最后一次形成longPress的时间变短
private int mCount;
//长按的runnable
private Runnable mLongPressRunnable;
//移动的阈值
private static final int TOUCH_SLOP = 20;
public LongClickLayout(@NonNull Context context) {
super(context);
createRunnable();
}
public LongClickLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
createRunnable();
}
public LongClickLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
createRunnable();
}
public LongClickLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public void createRunnable() {
mLongPressRunnable = new Runnable() {
@Override
public void run() {
mCount--;
//计数器大于0,说明当前执行的Runnable不是最后一次down产生的。
if (mCount > 0 || isReleased || isMoved) return;
Log.i(TAG, "执行了长按");
performLongClick();
}
};
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastMotionX = x;
mLastMotionY = y;
mCount++;
isReleased = false;
isMoved = false;
setPressed(true);
postDelayed(mLongPressRunnable, DEFAULT_TIME);
break;
case MotionEvent.ACTION_MOVE:
if(isMoved) break;
if(Math.abs(mLastMotionX-x) > TOUCH_SLOP
|| Math.abs(mLastMotionY-y) > TOUCH_SLOP) {
//移动超过阈值,则表示移动了
isMoved = true;
}
break;
case MotionEvent.ACTION_UP:
//释放了
isReleased = true;
setPressed(false);
break;
}
return true;
}
}
上面我是实现的一个继承自FrameLayout的长按事件,因为我的点击事件即是一个FrameLayout,如果有需要,亦可改为其它view。之后在xml文件中引用该view,并在需要的地方直接调用即可。
mBinding.btnPause.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// 需要执行的操作
return false;
}
});
参考文档:Android自定义长按事件