背景:
随着移动端的快速发展,实体按键已基本被触摸屏所取代,使用者和手机的信息交流,依赖于屏幕。屏幕不仅作为一个显示器,同样兼顾着输入设备,拥有输入输出两种功能,雌雄同体。
功能:点击,是屏幕使用最多的时候,系统提供的单击监听
public void setOnClickListener(@Nullable OnClickListener l) ,
如果需要双击,就需要通过手势监听来实现:GestureDetector
GestureDetector gestureDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
//双击
clickEvent(e, true);
return super.onDoubleTap(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
//单击
clickEvent(e, false);
return super.onSingleTapConfirmed(e);
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return super.onSingleTapUp(e);
}
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public void onShowPress(MotionEvent e) {
super.onShowPress(e);
}
@Override
public boolean onDown(MotionEvent e) {
return super.onDown(e);
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return super.onDoubleTapEvent(e);
}
@Override
public boolean onContextClick(MotionEvent e) {
return super.onContextClick(e);
}
});
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
//常见的两种回调
GestureDetector.SimpleOnGestureListener://简单的监听,已实现双击监听回调
GestureDetector.OnDoubleTapListener://双击监听
这是常见的手势监听,来完成。
但是这种监听是不支持时间订制,也就是双击间距和单击回调的时间机制,导致满足不了一些订制要求
解决方案:
我们可以通过模拟点击,来完成双击和单击,点击最核心是手势按下屏幕和离开,至于在屏幕上滑动MOVING,这些可以忽略,ACTION_DOWN到ACTION_UP的时间差,
接下来我们通过代码来完成模拟
/**
* @author :woniu
* @date:2022/4/27-17:56
* @wiki:
* @projectName:MyApplication
* @FileName:ViewTouchManager
* @descp:
*/
public class ViewTouchManager {
private static volatile ViewTouchManager manager;
private long mClickTime = 0;
private boolean clickEnable = false;
private boolean doubleClickEnable = false;
private long doubleClickTime = 0;
private boolean moving = false;
private long lasTime = 0;
private int clickCount = 0;
private final int MSG_CLICK = 0x101;//点击消息
private final int MSG_DOUBLE = 0x102;//双极性消息
private MyHandler myHandler;
private SimpleOnClickListener simpleOnClickListener;
private MotionEvent motionEvent;
private boolean doubleClick = false;
public static ViewTouchManager getInstance() {
if (manager == null)
manager = new ViewTouchManager();
return manager;
}
public ViewTouchManager setClickTime(boolean clickEnable, long clickTime) {
this.clickEnable = clickEnable;
this.mClickTime = clickTime;
return this;
}
public ViewTouchManager setOnDoubleClickTime(boolean clickEnable, long clicktime) {
this.doubleClickEnable = clickEnable;
this.doubleClickTime = clicktime;
return this;
}
public ViewTouchManager addClickListener(View view, SimpleOnClickListener simpleOnClickListener) {
this.simpleOnClickListener = simpleOnClickListener;
if (view == null)
return this;
if (myHandler == null) {
myHandler = new MyHandler();
}
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
motionEvent = event;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
moving = false;
lasTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_CANCEL: {
}
break;
case MotionEvent.ACTION_UP: {
long newTime = System.currentTimeMillis();
if (!moving) {
moving = false;
doubleClick = false;
long clicKTime = newTime - lasTime;
//双击
if (clicKTime < doubleClickTime && doubleClickEnable) {
clickCount++;
if (clickCount == 2) {
//双击
doubleClick = true;
clickCount = 0;
if (doubleClickEnable && simpleOnClickListener != null) {
simpleOnClickListener.onDoubleClick(event);
}
}
}
if (clicKTime < mClickTime) {
myHandler.sendEmptyMessageDelayed(MSG_CLICK, doubleClickEnable ? doubleClickTime : mClickTime);
}
lasTime = newTime;
}
}
break;
case MotionEvent.ACTION_MOVE: {
// moving = true;
}
break;
}
return true;
}
});
return this;
}
public interface SimpleOnClickListener {
public void onDoubleClick(MotionEvent event);
public void onClick(MotionEvent event);
}
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_CLICK: {
if (!doubleClick && clickCount != 2) {
//单击行为
clickCount = 0;
if (clickEnable && simpleOnClickListener != null) {
simpleOnClickListener.onClick(motionEvent);
}
} else if (!doubleClickEnable && clickEnable) {
if (clickEnable && simpleOnClickListener != null) {
simpleOnClickListener.onClick(motionEvent);
}
}
}
break;
}
}
}
}