想来也好久没到简书发东西了,其实一直在写着些有的没的,倒有想着年底把它们都发出来.今天之所以写下这篇是觉得有必要记录一下这种奇奇怪怪的问题,花费了我大半时间不说还没半点技术性质可言...好了废话不多说
场景重现:
因项目需要,开发者x某在充分了解了原型图后自定义了符合功能要求的自定义view(继承view而非ViewGroup),按着各个重写方法定制界面,事件处理(onTouchEvent())后测试功能通过,后产品加需求需要在当前功能不变下添加点击监听,遂setOnClickListener()方法,测试发现onClick方法不执行.
故障代码:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DWON:
//业务代码
return true/false;
break;
case MotionEvent.ACTION_UP:
//业务代码
return true/false;
break;
...
}
return super.onTouchEvent(event);
}
故障分析:
通过上面描述不难发现,onClick()方法肯定跟触摸监听onTouchEvent()方法起"冲突"了,这个冲突是怎么产生的呢?
我们不妨先来了解下在android源码中onCLick()方法的执行前提,以下是View类的onTouchEvent方法:
public boolean onTouchEvent(MotionEvent event) {
...
case MotionEvent.ACTION_UP:
if (!focusTaken) {
performClick(); //onClick方法将会在该方法中调用
}
}
...
}
说白了就是得有消费up事件,看到这里x某回想了自己编写过的代码,在up分支里是有返回true的啊?查阅了一番文档问题得不到解决的x某心烦意乱,慌乱中瞥见了自己重写的onTouchEvent方法有一项warning:
Custom view xxx(自定义view类名) overrides onTouchEvent but not performClick
心烦意乱的x某化身可达鸭
言下之意就是自定义的view重写了onTouchEvent方法后却没有调用performClick()方法,而这个方法恰好是onClick的入口方法...
翻译到这里,x某再次修改了代码:
@Override
public boolean performClick() {
return super.performClick();
)
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DWON:
//业务代码
return true/false;
break;
case MotionEvent.ACTION_UP:
//业务代码
performClick();
return true/false;
break;
...
}
return super.onTouchEvent(event);
}
测试onClick执行,又可以跟产品愉快的玩耍la~~~
结论
自定义的view重写了onTouchEvent方法后,还想要响应onClick方法的话,最好在up事件里调用一下performClick()方法...
网友评论