android事件分发

来源:互联网 发布:网络营业执照 淘宝 编辑:程序博客网 时间:2024/06/05 12:02

点击事件会按照 Activity-window-View的顺序从上到下依次传递,中间会有各种乱七八糟的方法调用,如果最底层也就是View在OnTouchEvent中也返回false时,然后就由Activity处理这次点击事件,

Activity的相关源码在这里,下面这个是dispatchTouchEvent的源码:

    /**
     * Called to process touch screen events.  You can override this to
     * intercept all touch screen events before they are dispatched to the
     * window.  Be sure to call this implementation for touch screen events
     * that should be handled normally.
     *
     * @param ev The touch screen event.
     *
     * @return boolean Return true if this event was consumed.
     */
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

然后是onUserInteraction()方法,这个方法不是说的重点,虽然它也很重要,有空再说它:

    /**
     * Called whenever a key, touch, or trackball event is dispatched to the
     * activity.  Implement this method if you wish to know that the user has
     * interacted with the device in some way while your activity is running.
     * This callback and {@link #onUserLeaveHint} are intended to help
     * activities manage status bar notifications intelligently; specifically,
     * for helping activities determine the proper time to cancel a notfication.
     *
     * <p>All calls to your activity's {@link #onUserLeaveHint} callback will
     * be accompanied by calls to {@link #onUserInteraction}.  This
     * ensures that your activity will be told of relevant user activity such
     * as pulling down the notification pane and touching an item there.
     *
     * <p>Note that this callback will be invoked for the touch down action
     * that begins a touch gesture, but may not be invoked for the touch-moved
     * and touch-up actions that follow.
     *
     * @see #onUserLeaveHint()
     */
    public void onUserInteraction() {
    }

我们看到在dispatchTouchEvent方法中会先让Activity的Window处理这个事件,如果一层一层传下去后,也就是View的OnTouchEvent返回的也是false的话,getWindow().superDispatchTouchEvent(ev)这个方法返回的是false,那么就让这个Activity的onTouchEvent处理这个点击事件。

需要注意的是View并没有dispatchTouchEvent,因为View已经是最底层了,没必要再继续DispatchTouchEvent了。回到原始的问题,也就是说View的onTouchEvent返回false时,会让这个View所在的Activity处理这次点击事件。

然后说下View几个比较重要的容易混淆的方法先后顺序:

这个是在View中定义的一个接口:

    /**
     * Interface definition for a callback to be invoked when a touch event is
     * dispatched to this view. The callback will be invoked before the touch
     * event is given to the view.
     */
    public interface OnTouchListener {
        /**
         * Called when a touch event is dispatched to a view. This allows listeners to
         * get a chance to respond before the target view.
         *
         * @param v The view the touch event has been dispatched to.
         * @param event The MotionEvent object containing full information about
         *        the event.
         * @return True if the listener has consumed the event, false otherwise.
         */
        boolean onTouch(View v, MotionEvent event);
    }

然后是自己的一个私有成员变量:

private OnTouchListener mOnTouchListener;

这个第一个方法,然后View还有个方法onTouchEvent(MotionEvent event):

    /**
     * Implement this method to handle touch screen motion events.
     * <p>
     * If this method is used to detect click actions, it is recommended that
     * the actions be performed by implementing and calling
     * {@link #performClick()}. This will ensure consistent system behavior,
     * including:
     * <ul>
     * <li>obeying click sound preferences
     * <li>dispatching OnClickListener calls
     * <li>handling {@link AccessibilityNodeInfo#ACTION_CLICK ACTION_CLICK} when
     * accessibility features are enabled
     * </ul>
     *
     * @param event The motion event.
     * @return True if the event was handled, false otherwise.
     */
    public boolean onTouchEvent(MotionEvent event) {}

还有个最常用的方法setOnclickListener(OnClickListener l):

    /**
     * Register a callback to be invoked when this view is clicked. If this view is not
     * clickable, it becomes clickable.
     *
     * @param l The callback that will run
     *
     * @see #setClickable(boolean)
     */
    public void setOnClickListener(OnClickListener l) {}

这三个方法的优先级依次是:onTouchListener中的onTouch(View v, MotionEvent event);最高,onTouchEvent(MotionEvent event) {}次之,void onClick(View v);最低。


欢迎有问题的。

0 0
原创粉丝点击