版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/reakingf/article/details/80324642
最近在项目中遇到了首次点击View时,第一次总是没有触发,通过设置press的背景可以看到确实是有点击到的,但是就是没有触发点击事件,最后看了下View的源码发现原来是xml中的这个属性导致的android:focusableInTouchMode="true"
。通过源码可以发现,当该属性为ture时,ACTION_UP时,如果该View没有获取焦点,变回直接获取焦点,然后不触发点击事件,所以第一次点击时一般都没有获取焦点,从而导致点击事件无法触发,因此只要将该属性去掉或改为false即可。源码如下:
//in View.java
public boolean onTouchEvent(MotionEvent event) {
...
if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {
switch (action) {
case MotionEvent.ACTION_UP:
...
if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
// take focus if we don't have it already and we should in
// touch mode.
boolean focusTaken = false;
if (isFocusable()
&& isFocusableInTouchMode() //若xml里面的focusableInTouchMode为true
&& !isFocused()) { // 且没获取焦点,则会请求获取焦点
focusTaken = requestFocus();//成功获取焦点后focusTaken为true
}
...
if (!focusTaken) { //由于focusTaken为true,因而里面的post(mPerformClick)或performClick()都无法执行,因此便会导致首次点击不触发点击事件的问题
// Use a Runnable and post this rather than calling
// performClick directly. This lets other visual state
// of the view update before click actions start.
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClick();
}
}
...
break;
...