View点击事件

1、关于控件点击事件

Android中TextView、Button、ImageView等等控件都可以实现点击事件,下面以TextView和Button举例

view.setOnTouchListener(new OnTouchListener() {
<span style="white-space:pre">	</span>@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		return false;
	}
});
TextView与Button分别实现OnTouchListener监听事件,两个控件分别进行一次点击事件执行如下:

TextView的onTouch方法执行一次

Button的onTouch方法执行两次

修改一:将reutrn false 改为 true

TextView的onTouch方法执行两次

Button的onTouch方法执行两次

修改二:两个控件分别实现点击事件

view.setOnClickListener(new OnClickListener() {
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
						
	}
});
运行结果:TextView的onTouch方法执行两次

    Button的onTouch方法执行两次

2、原因分析
当用户触摸屏幕时,系统会把一系列的触摸事件封装成一个MotionEvent对象,然后通过dispatchTouchEvent进行事件分发,关于事件分发,下面将会提到。

onTouch()方法之所以被执行,是因为View中dispatchTouchEvent()会调用onTouch()方法

而进行事件分发时判断

是否实现了OnTouchListener接口的onTouch方法

是否可被点击

onTouch()方法返回值

以上会造成onTouch()方法至少调用一次调用,如果返回true表示消费此事件,将会执行第二次

如果onTouch()方法此时返回false,此时是否执行第二次,由是否可点击决定,View的部分源码如下

if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
           && li.mOnTouchListener.onTouch(this, event)) {
      return true;
}

if (onTouchEvent(event)) {
      return true;
}
onTouchEvent方法会判断该控件是否可点击,而Button默认就是可点击的,所以导致前面Button未作任何设置都不会影响其onTouch方法的执行

    public void setOnClickListener(OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }
只要设置了onClick方法,那么就会被设置为可点击,该控件就会消费后面的事件
3、事件的分发

Android的事件通过分发-拦截-处理几个步骤,通过FrameLayout、LinearLayout、TextView三个控件来了解分发的次序

public boolean dispatchTouchEvent(MotionEvent event){
	L.i("---> start");
	boolean b = super.dispatchTouchEvent(event);
	L.i("---> end");
	return b;	
}

1、FrameLayout

|-- LinearLayout

|-- TextView

点击事件执行结果

点击FrameLayout: FrameLayout --->start --->end

点击LinearLayout: FrameLayout start ---> LinearLayout start ---> LinearLayout end ---> FrameLayout end

点击TextView:FrameLayout start ---> LinearLayout start ---> TextView start ---> TextView end --- >LinearLayout end ---> FrameLayout end

2、FrameLayout

| -- LinearLayout

| -- TextView

点击事件执行结果

FrameLayout与LinearLayout结果与上面相同

TextView:FrameLayout start ---> TextView start ---> TextView end ---> LinearLayout start ---> LinearLayout end ---> FrameLayout end

FrameLayout发现子View按倒序进行事件分发 ,从源码得知:for(int i=count-1;i>=0;i--)


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值