想來也好久沒到簡書發(fā)東西了,其實一直在寫著些有的沒的,倒有想著年底把它們都發(fā)出來.今天之所以寫下這篇是覺得有必要記錄一下這種奇奇怪怪的問題,花費了我大半時間不說還沒半點技術(shù)性質(zhì)可言...好了廢話不多說
場景重現(xiàn):
因項目需要,開發(fā)者x某在充分了解了原型圖后自定義了符合功能要求的自定義view(繼承view而非ViewGroup),按著各個重寫方法定制界面,事件處理(onTouchEvent())后測試功能通過,后產(chǎn)品加需求需要在當(dāng)前功能不變下添加點擊監(jiān)聽,遂setOnClickListener()方法,測試發(fā)現(xiàn)onClick方法不執(zhí)行.
故障代碼:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DWON:
//業(yè)務(wù)代碼
return true/false;
break;
case MotionEvent.ACTION_UP:
//業(yè)務(wù)代碼
return true/false;
break;
...
}
return super.onTouchEvent(event);
}
故障分析:
通過上面描述不難發(fā)現(xiàn),onClick()方法肯定跟觸摸監(jiān)聽onTouchEvent()方法起"沖突"了,這個沖突是怎么產(chǎn)生的呢?
我們不妨先來了解下在android源碼中onCLick()方法的執(zhí)行前提,以下是View類的onTouchEvent方法:
public boolean onTouchEvent(MotionEvent event) {
...
case MotionEvent.ACTION_UP:
if (!focusTaken) {
performClick(); //onClick方法將會在該方法中調(diào)用
}
}
...
}
說白了就是得有消費up事件,看到這里x某回想了自己編寫過的代碼,在up分支里是有返回true的啊?查閱了一番文檔問題得不到解決的x某心煩意亂,慌亂中瞥見了自己重寫的onTouchEvent方法有一項warning:
Custom view xxx(自定義view類名) overrides onTouchEvent but not performClick
言下之意就是自定義的view重寫了onTouchEvent方法后卻沒有調(diào)用performClick()方法,而這個方法恰好是onClick的入口方法...
翻譯到這里,x某再次修改了代碼:
@Override
public boolean performClick() {
return super.performClick();
)
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DWON:
//業(yè)務(wù)代碼
return true/false;
break;
case MotionEvent.ACTION_UP:
//業(yè)務(wù)代碼
performClick();
return true/false;
break;
...
}
return super.onTouchEvent(event);
}
測試onClick執(zhí)行,又可以跟產(chǎn)品愉快的玩耍la~~~
結(jié)論
自定義的view重寫了onTouchEvent方法后,還想要響應(yīng)onClick方法的話,最好在up事件里調(diào)用一下performClick()方法...