//1.事件在Activity 中的傳遞
public boolean dispatchTouchEvent(MotionEvent ev) {
//按下事件
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
//空方法,當用戶點擊屏幕時會調用這個方法,可用來實現屏幕保護
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
//如果所有的view 都不消費該事件,那麼事件最終會到達 activity 的onTouchEvent
//相反、如果上一步getWindow().superDispatchTouchEvent(ev) 返回true 那麼不會到達
//activity 的onTouchEvent(ev)
return onTouchEvent(ev);
}
//註釋說默認實現永遠返回false
public boolean onTouchEvent(MotionEvent event) {
if (mWindow.shouldCloseOnTouch(this, event)) {
finish();
return true;
}
return false;
}
總結:事件在activity的傳遞,事件從activity的dispatchTouchEvent開始,傳遞給getWindow().superDispatchTouchEvent(ev),如果返回false 那麼將會傳遞給自己的
onTouchEvent(默認實現返回false)
//2.事件在Window 中的傳遞 window 是抽象類,實現類phonewindow
//Activity 通過getWindow().superDispatchTouchEvent(ev),將事件傳遞給了window 對象
//window decor 的關係,activity.setContentView() 的時候會創建DecorView,並根據Theme中的//Feature 選擇contentParent 佈局,setContentView 最終是添加到contentParent 中id 爲//ID_ANDROID_CONTENT中
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
//將事件傳遞到DecorView 中
return mDecor.superDispatchTouchEvent(event);
}
//3.事件在ViewGroup中傳遞
DecorView
public boolean superDispatchTouchEvent(MotionEvent event) {
//調用父類ViewGroup 的dispatchTouchEvent
return super.dispatchTouchEvent(event);
}
事件在ViewGroup 中傳遞的僞代碼
public boolean dispatchTouchEvent(MotionEvent ev){
//1.決定是否由自己處理
if(允許攔截(disallowIntercept) && onInterceptTouchEvent(ev)){
//調用父類View 的dispatchTouchEvent 即交給自己處理
return super.dispatchTouchEvent(ev)
}
// 2.通過for循環,遍歷了當前ViewGroup下的所有子View
for(int i = 0;i<childCount;i++){
View child = getchildAt(i);
if(child.dispatchTouchEvent(ev)){
return true;
}
}
//3.如果沒有攔截,但是所有的子view 都不處理 和第一步一樣 同在View 的傳遞
return super.dispatchTouchEvent(ev)
}
}
事件在View 中的傳遞僞代碼
public boolean dispatchTouchEvent(MotionEvent ev){
//1.如果設置了ontouchlistener (mViewFlags & ENABLED_MASK) == ENABLED
//如果mOnTouchListener.onTouch 返回true 則直接返回true 事件分發結束
//否則 調用onTouchEvent(event)
if(ENABLED && mOnTouchListener.onTouch(ev)){
return true;
}else{
return onTouchEvent(event);
}
}
public boolean onTouchEvent(MotionEvent event){
//如果view 可點擊,但卻是DISABLED
if(clickable && DISABLED){
return true;
}
//如果可點擊一定返回true 否則返回false
if(clickable ){
performClick()
return true
}else{
return false
}
}
public boolean performClick(){
如果設置了onclickListener 返回true
否則返回false
}
總結:事件的整個流程
1.Activity
dispatchTouchEvent(MotionEvent ev){
if(window.superDispatchTouchEvebt()){
return true;
}
//如果所有的view 都不處理,就到activity 的onTouchEvent()默認返回false
return onTouchEvent();
}
2.ViewGroup
dispatchTouchEvent(MotionEvent ev){
1.是否允許攔截並且攔截->把自己當成一個view ->view.dispatchTouchEvent()
2.不攔截 遍歷子控件->child.dispatchTouchEvent() 如果子控件返回true 那麼事件傳遞結束
3.如果不攔截、子控件也不處理->把自己當成一個view->View.dispatchTouchEvent()
}
3.View
dispatchTouchEvent(MotionEvent ev){
1.enabled 並且設置了 ontouchListener->listener.onTouch()
如果ontouch 返回true ,返回true 事件分發結束
2.如果沒設置ontouchListener 或者 前面的onTouch 返回false
->onTouchEvent(ev)
}
onTouchEvent(ev){
1.如果clickable 判斷是點擊事件->performClick 返回true
2.不可點擊 返回false
}
performClick(){
//設置clickListener 返回true
//否則返回false
}