菜鸟上路,个人见解,有错误的地方请多指教
OnClickListener是安卓控件的一个点击监听事件 这个接口 包含一个方法 void onClick(View v)
进去看源码会比较神奇的发现 view中
public void setOnClickListener(OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
这个方法只是把控件设置为可以点击以及把 监听给予ListenerInfo
ListenerInfo getListenerInfo() {
if (mListenerInfo != null) {
return mListenerInfo;
}
mListenerInfo = new ListenerInfo();
return mListenerInfo;
}
至于ListenerInfo 是view中的一个静态类 里面定义了view的监听 点击长按 等等
在设置监听的时候没有触发onClick这个方法 那么这个方法在哪里调用了呢?
不难找到
public boolean performClick() {
final boolean result;
final ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
result = true;
} else {
result = false;
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
return result;
}
if判断语句这个很简单 就不说了 if语句第一句是处理声音的 li.mOnClickListener.onClick(this) 这个就是处理onClick方法了 所以控件设置的onclick 返回的v即是它本身
然后performClick()的调用 会发现是在onTouchEvent中 这个方法可能都很熟悉 对的 就是手势的方法 既然手势触发的方法 那么就必须了解
dispatchTouchEvent了 这个方法首先你需要知道一点,只要你触摸到了任何一个控件,就一定会调用该控件的dispatchTouchEvent方法
这个方法里面有个代码很关键
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
当然其中控件都是ENABLED的 mOnTouchListener是控件setOnTouchListener需要实现的接口
此接口 有个boolean方法onTouch 再看上面的if语句 如果控件设置了setOnTouchListener 那么前面的条件都满足 重要的是最后一个条件
li.mOnTouchListener.onTouch(this, event) 即是看你处理的onTouch方法是不是为true 都满足的话 那么就不会执行下面的onTouchEvent方法了
到这里就已经很清楚了 onclick 方法 执行的过程是 dispatchTouchEvent -- onTouchEvent中的手势ACTION_UP
下面写个列子
tv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("tv---onClick --", "执行");
}
});
tv.setOnTouchListener(new OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("tv---onTouch --event action", String.valueOf(event.getAction()));
return true;
}
});
当OnTouch返回true的时候 onClick方法不会被调用
这只是个单独的view 碰触的过程 至于viewpager嵌套viewpager ScrollView与listView 这些即是ViewGroup事件分发 拦截 消费了 详情请看http://www.android100.org/html/201406/04/18048.html 写得真心不错