答案:
這個(gè)問題可以寫個(gè)長(zhǎng)篇大論,但在面試時(shí)被問到時(shí)要從以下幾個(gè)方面入手。
記住這個(gè)原則:Android的事件總是從父控件往子控件分發(fā)。子控件都不處理時(shí)事件再回傳父控件。很多問題可以根據(jù)這個(gè)原則推導(dǎo)出來。
三個(gè)方法:
dispatchTouchEvent:負(fù)責(zé)接收事件,返回false則表示向子控件分發(fā)事件。
onInterceptTouchEvent:返回true表示攔截,同時(shí)調(diào)用onTouchEvent方法。
onTouchEvent:處理事件,一般重寫此方法,返回true表示消耗掉該事件并不再傳遞下去,返回false表示不處理事件并把事件退回父控件。
View和ViewGroup
所有的控件都繼承自View。
所有的布局都繼承自ViewGroup,ViewGroup則繼承自View。
View沒有onInterceptToutchEvent方法,所以dispatchTouchEvent直接調(diào)用onTouchEvent。
流程(Activity > ViewGroup > View)
Activity是事件的起點(diǎn),事件分被封裝成MotionEvent對(duì)象發(fā)給Activity的dispatchTouchEvent方法。
dispatchTouchEvent內(nèi)部會(huì)把事件傳給setContentView指定的布局,即根布局ViewGroup。
根布局的dispatchTouchEvent在接收到事件后調(diào)用onInterceptTouchEvent方法。
onInterceptTouchEvent方法會(huì)判斷是否攔截該事件,如果攔截就將事件傳給onTouchEvent方法處理。不攔截就直接把事件傳給子控件。
onTouchEvent方法負(fù)責(zé)處理事件,返回值決定是否要消費(fèi)掉該事件,返回true表示以后由此控件來處理該事件,返回false表示以后也不再接收該事件。
當(dāng)所有控件的onTouchEvent都返回false時(shí)事件由Activity的onTouchEvent來處理。
優(yōu)先級(jí)
OnTouchListener,onTouchEvent,onClickListener執(zhí)行順序
onTouch(ACTION_DOWN) => onTouchEvent(ACTION_DOWN) => onTouch(ACTION_UP) =>? onTouchEvent(ACTION_UP) => onClick