Android开发艺术探索学习-View的事件分发机制(二)

来源:互联网 发布:cba球员卧推数据 编辑:程序博客网 时间:2024/05/20 16:41

    这节主要是透过源码来分析触摸事件是如何从Activity传递到View中。    

    当一个点击事件发生时,最先接受到事件的是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) {        /*         * 在ACTION_DOWN的时候,调用onUserInteraction方法,         * 这个方法的作用稍后解释          * **/        if (ev.getAction() == MotionEvent.ACTION_DOWN) {            onUserInteraction();        }        //如果Window的superDispatchTouchEvent返回true,说明事件被消费        //如果返回false,则由Activity自身消费,即调用其onTouchEvent方法        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() {    }

    当有键盘、触摸或者轨迹球事件分发给Activity的时候,你可以知道用户是否正在交互。与其对应的还有一个回调方法onUserLeaveHint,这两个方法可以很好地帮助Activity管理状态栏上的通知,显然也可以帮助Activity在合适的时间取消通知。接着我们看下onUserLeaveHint的代码。

    /**     * Called as part of the activity lifecycle when an activity is about to go     * into the background as the result of user choice.  For example, when the     * user presses the Home key, {@link #onUserLeaveHint} will be called, but     * when an incoming phone call causes the in-call Activity to be automatically     * brought to the foreground, {@link #onUserLeaveHint} will not be called on     * the activity being interrupted.  In cases when it is invoked, this method     * is called right before the activity's {@link #onPause} callback.     *     * <p>This callback and {@link #onUserInteraction} are intended to help     * activities manage status bar notifications intelligently; specifically,     * for helping activities determine the proper time to cancel a notfication.     *     * @see #onUserInteraction()     */    protected void onUserLeaveHint() {   
    当某Activity因为用户操作进入后台,那么onUserLeaveHint将被调用并作为activity生命周期的部分。例如当用户按下home键的时候,onUserLeaveHint将被调用,但是当有来电的时候,那么in-call Activity将自动进入前台,这时onUserLeaveHint将不被调用。

    接着还是继续分析Activity的dispatchTouchEvent方法,在该方法中调用了抽象类Window的superDispatchTouchEvent方法,作用是将触屏事件继续传递到View层中,其代码如下:

    /**     * Used by custom windows, such as Dialog, to pass the touch screen event     * further down the view hierarchy. Application developers should     * not need to implement or call this.     *     */    public abstract boolean superDispatchTouchEvent(MotionEvent event);

    该方法的具体实现是在PhoneWindow类中,其代码如下:
    @Override    public boolean superDispatchTouchEvent(MotionEvent event) {        return mDecor.superDispatchTouchEvent(event);    }
    这里,我们可以看到其调用了mDecor的superDispatchTouchEvent方法,mDecor是个啥玩意呢?
    // This is the top-level view of the window, containing the window decor.    private DecorView mDecor;
    原来mDecor是DecorView,它是Window的顶级View,关于DecorView后续将会有分析,我们需要知道它继承自FrameLayout。DecorView的superDispatchTouchEvent方法代码如下:

        public boolean superDispatchTouchEvent(MotionEvent event) {            return super.dispatchTouchEvent(event);        }

   到这里,就是调用了FrameLayout的dispatchTouchEvent方法。再往下就是正常的View事件传递过程。







1 0
原创粉丝点击