Android 自定义双击和单击事件,支持时间间隔

背景:

随着移动端的快速发展,实体按键已基本被触摸屏所取代,使用者和手机的信息交流,依赖于屏幕。屏幕不仅作为一个显示器,同样兼顾着输入设备,拥有输入输出两种功能,雌雄同体。

功能:点击,是屏幕使用最多的时候,系统提供的单击监听

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;
            }

        }
    }

}

目前该工具类支持:单击事件,双击事件,也支持但双击事件的时间订制,如果你需要哪个,只需开启即可。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值