(未完)Android 点击事件响应总结

一、从Activity/Dialog到DecorView

Activity或Dialog先响应到dispatchTouchEvent()事件,拿Activity为例

public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();
    }
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}

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.
其中,getWindow()返回的是Activity的mWindow对象,其被初始化为PhoneWindow

mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);

插一段介绍setCallback()方法,它的参数为Window.Callback接口,里面有一些常用的方法,比如

public boolean dispatchTouchEvent(MotionEvent event);

Called to process touch screen events. At the very least your implementation must call superDispatchTouchEvent(MotionEvent) to do the standard touch screen processing.
boolean Return true if this event was consumed.

public void onWindowFocusChanged(boolean hasFocus);

This hook is called whenever the window focus changes. See View.onWindowFocusChangedNotLocked(boolean) for more information.

public void onAttachedToWindow();

Called when the window has been attached to the window manager. See View.onAttachedToWindow() for more information.

public void onDetachedFromWindow();

Called when the window has been attached to the window manager. See View.onDetachedFromWindow() for more information.

回到Activity的dispatchTouchEvent(MotionEvent)方法,它调用了PhoneWindow的superDispatchTouchEvent(MotionEvent)方法

@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
    return mDecor.superDispatchTouchEvent(event);
}

mDecor是DecorView类型的变量,看下它的superDispatchTouchEvent()方法

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

调用了它的父类(FrameLayout)的父类(ViewGroup)的dispatchTouchEvent(MotionEvent)方法。
再次回到Activity的dispatchTouchEvent()方法,如果事件未被消耗(getWindow().superDispatchTouchEvent(ev)返回false),则会调用Activity的onTouchEvent(MotionEvent)方法。

二、从DecorView到ContentView
2.1 先说下PhoneWindow与DecorView的关系

PhoneWindow中DecorView类型变量为mDecor,它的初始化在installDecor()中

    private void installDecor() {
        mForceDecorInstall = false;
        if (mDecor == null) {
            mDecor = generateDecor(-1);
            ...  
        } else {
            mDecor.setWindow(this);
        }
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);

            // Set up decor part of UI to ignore fitsSystemWindows if appropriate.
            mDecor.makeOptionalFitsSystemWindows();
            ... 
            }
        }
    }            

其中,generateDecor(int)方法创建了DecorView对象

    protected DecorView generateDecor(int featureId) {
        ...
        return new DecorView(context, featureId, this, getAttributes());
    }

调用了DecorView的构造方法

    DecorView(Context context, int featureId, PhoneWindow window,
            WindowManager.LayoutParams params) {
        super(context);
        ...
        setWindow(window); // 将PhoneWindow保存到DecorView的mWindow变量中
        ...
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值