美文网首页
Android 事件分发体系

Android 事件分发体系

作者: 盐海里的鱼 | 来源:发表于2020-07-13 01:54 被阅读0次
小案例:分析setOnTouchListener 与setOnClickListener导致的冲突

场景:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener{
            Log.d("TAG", "onclick")

        }
        button.setOnTouchListener { v, event ->
            Log.d("TAG", "OnTouch:$v->${event.action}")
            true
        }
    }
}

**setOnTouchListener 返回true时 打印:**
TAG: OnTouch
TAG: OnTouch
**setOnTouchListener 返回false时 打印:**
TAG: OnTouch
TAG: OnTouch
TAG: onclick

可以看到为false时onclick触发了

事件分流体系与ViewGroup继承关系
分析源码
1. 从view的dispatchTouchEvent中:
 if (onFilterTouchEventForSecurity(event)) {
            if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
                result = true;
            }
            //noinspection SimplifiableIfStatement
            ListenerInfo li = mListenerInfo;
            //li setonTouchListener 时已经赋值不会为null
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    //这里就是setonTouchListener的返回结果影响的 返回true 命中整个if,result此时为true
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }
            //当result为true 第一个条件判断为false 直接不走整个逻辑 此时onTouchEvent 不会触发
            if (!result && onTouchEvent(event)) {
                result = true;
            }
        }
  1. li.mOnTouchListener.onTouch(this, event)该结果影响到了result的值
2. 当result为false时,从View的 onTouchEvent中看 onclick的触发时机:
在 case MotionEvent.ACTION_UP 中:
   // Only perform take click actions if we were in the pressed state
  ...
  if (!post(mPerformClick)) {
   performClickInternal();
  }
}

再看看performClickInternal()
private boolean performClickInternal() {
         ...
        return performClick();
 }

performClick() 就是触发onClick的时机:
public boolean performClick() {
       ...
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            //这里触发了onclick回调
            li.mOnClickListener.onClick(this);
            result = true;
        } else {
            result = false;
        }
       ...
        return result;
    }

相关文章

网友评论

      本文标题:Android 事件分发体系

      本文链接:https://www.haomeiwen.com/subject/vpeocktx.html