Input系统学习-----GestureDetector的设计

在应用中,监听到点击事件会调用到

onTouch(MotionEvent e) 方法,

怎么来识别是什么点击操作呢,常用的事件主要是点击,长按,滑动等,

我们可以写方法来进行识别判断,

写一个判断方法,如果是点击,就调用相应的处理,长按,就调用长按的处理方法,

可以设计一个观察者模式listener来进行实现,

Google也是这么想的,Android中提供了GestureDetector 来进行常规手势的识别处理,

GestureDetector的用法可以参考

https://www.cnblogs.com/ldq2016/p/7000300.html

https://www.cnblogs.com/yuanhao-1999/p/11081980.html

这里我们来看看GestureDetector的设计,

为了方便进行相应的操作,定义了listener接口,

40public class GestureDetector {
41    /**
42     * The listener that is used to notify when gestures occur.
43     * If you want to listen for all the different gestures then implement
44     * this interface. If you only want to listen for a subset it might
45     * be easier to extend {@link SimpleOnGestureListener}.
46     */
47    public interface OnGestureListener {
48
49        /**
50         * Notified when a tap occurs with the down {@link MotionEvent}
51         * that triggered it. This will be triggered immediately for
52         * every down event. All other events should be preceded by this.
53         *
54         * @param e The down motion event.
55         */
56        boolean onDown(MotionEvent e);
57
58        /**
59         * The user has performed a down {@link MotionEvent} and not performed
60         * a move or up yet. This event is commonly used to provide visual
61         * feedback to the user to let them know that their action has been
62         * recognized i.e. highlight an element.
63         *
64         * @param e The down motion event
65         */
66        void onShowPress(MotionEvent e);
67
68        /**
69         * Notified when a tap occurs with the up {@link MotionEvent}
70         * that triggered it.
71         *
72         * @param e The up motion event that completed the first tap
73         * @return true if the event is consumed, else false
74         */
75        boolean onSingleTapUp(MotionEvent e);
76
77        /**
78         * Notified when a scroll occurs with the initial on down {@link MotionEvent} and the
79         * current move {@link MotionEvent}. The distance in x and y is also supplied for
80         * convenience.
81         *
82         * @param e1 The first down motion event that started the scrolling.
83         * @param e2 The move motion event that triggered the current onScroll.
84         * @param distanceX The distance along the X axis that has been scrolled since the last
85         *              call to onScroll. This is NOT the distance between {@code e1}
86         *              and {@code e2}.
87         * @param distanceY The distance along the Y axis that has been scrolled since the last
88         *              call to onScroll. This is NOT the distance between {@code e1}
89         *              and {@code e2}.
90         * @return true if the event is consumed, else false
91         */
92        boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
93
94        /**
95         * Notified when a long press occurs with the initial on down {@link MotionEvent}
96         * that trigged it.
97         *
98         * @param e The initial on down motion event that started the longpress.
99         */
100        void onLongPress(MotionEvent e);
101
102        /**
103         * Notified of a fling event when it occurs with the initial on down {@link MotionEvent}
104         * and the matching up {@link MotionEvent}. The calculated velocity is supplied along
105         * the x and y axis in pixels per second.
106         *
107         * @param e1 The first down motion event that started the fling.
108         * @param e2 The move motion event that triggered the current onFling.
109         * @param velocityX The velocity of this fling measured in pixels per second
110         *              along the x axis.
111         * @param velocityY The velocity of this fling measured in pixels per second
112         *              along the y axis.
113         * @return true if the event is consumed, else false
114         */
115        boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
116    }
117
118    /**
119     * The listener that is used to notify when a double-tap or a confirmed
120     * single-tap occur.
121     */
122    public interface OnDoubleTapListener {
123        /**
124         * Notified when a single-tap occurs.
125         * <p>
126         * Unlike {@link OnGestureListener#onSingleTapUp(MotionEvent)}, this
127         * will only be called after the detector is confident that the user's
128         * first tap is not followed by a second tap leading to a double-tap
129         * gesture.
130         *
131         * @param e The down motion event of the single-tap.
132         * @return true if the event is consumed, else false
133         */
134        boolean onSingleTapConfirmed(MotionEvent e);
135
136        /**
137         * Notified when a double-tap occurs.
138         *
139         * @param e The down motion event of the first tap of the double-tap.
140         * @return true if the event is consumed, else false
141         */
142        boolean onDoubleTap(MotionEvent e);
143
144        /**
145         * Notified when an event within a double-tap gesture occurs, including
146         * the down, move, and up events.
147         *
148         * @param e The motion event that occurred during the double-tap gesture.
149         * @return true if the event is consumed, else false
150         */
151        boolean onDoubleTapEvent(MotionEvent e);
152    }
153

识别处理,

    public boolean onTouchEvent(MotionEvent ev) {

556            case MotionEvent.ACTION_DOWN:
557                if (mDoubleTapListener != null) {
558                    boolean hadTapMessage = mHandler.hasMessages(TAP);
559                    if (hadTapMessage) mHandler.removeMessages(TAP);
560                    if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null)
561                            && hadTapMessage
562                            && isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
563                        // This is a second tap
564                        mIsDoubleTapping = true;
565                        // Give a callback with the first tap of the double-tap
566                        handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
567                        // Give a callback with down event of the double-tap
568                        handled |= mDoubleTapListener.onDoubleTapEvent(ev);
569                    } else {
570                        // This is a first tap
571                        mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
572                    }

识别出相应的手势后,通过handle机制的sendMessage来把事件抛出去,由UI主线程去处理,GestureDetector初始化的时候已经构造了handle对象

351    /**
352     * Creates a GestureDetector with the supplied listener.
353     * You may only use this constructor from a {@link android.os.Looper} thread.
354     * @see android.os.Handler#Handler()
355     *
356     * @param context the application's context
357     * @param listener the listener invoked for all the callbacks, this must
358     * not be null.
359     *
360     * @throws NullPointerException if {@code listener} is null.
361     */
362    public GestureDetector(Context context, OnGestureListener listener) {
363        this(context, listener, null);
364    }
365
366    /**
367     * Creates a GestureDetector with the supplied listener that runs deferred events on the
368     * thread associated with the supplied {@link android.os.Handler}.
369     * @see android.os.Handler#Handler()
370     *
371     * @param context the application's context
372     * @param listener the listener invoked for all the callbacks, this must
373     * not be null.
374     * @param handler the handler to use for running deferred listener events.
375     *
376     * @throws NullPointerException if {@code listener} is null.
377     */
378    public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
379        if (handler != null) {
380            mHandler = new GestureHandler(handler);
381        } else {
382            mHandler = new GestureHandler();
383        }
384        mListener = listener;
385        if (listener instanceof OnDoubleTapListener) {
386            setOnDoubleTapListener((OnDoubleTapListener) listener);
387        }
388        if (listener instanceof OnContextClickListener) {
389            setContextClickListener((OnContextClickListener) listener);
390        }
391        init(context);
392    }

GestureDetector的设计还是非常经典的观察者模式调用,同时里面用到了handle消息分发。

这个设计方法可以给我们启发来进行类似的功能设计。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值