您的位置:首页 > 移动开发 > Android开发

详解android中OnClickListener监听

2015-08-24 16:15 411 查看
菜鸟上路,个人见解,有错误的地方请多指教

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  写得真心不错
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  安卓 onclick onTouch