`
阿尔萨斯
  • 浏览: 4186104 次
社区版块
存档分类
最新评论

Activity-ViewGroup_onInterceptTouchEvent动作拦截机制(7)

 
阅读更多

同样,先总结后事例:

通过源码,我们知道ViewGroup继承了View,在触摸事件机制中,比View多了一个onInterceptTouchEvent的方法,正是这个方法实现了事件机制的拦截.从上章知,点击事件的机制是从获取焦点的View的onTouchEvent事件向外传递的.在此之前 会调用该

View所在的最外层Layout的onInterceptTouchEvent方法,由它来控制是否拦截该事件:

默认,我们不重写该方法,可直接在View的onTouchEvent监听事件,测试打印结果,默认onInterceptTouchEvent的Action_Down返回false.


由此可得onInterceptTouchEvent的Action_Down返回false时,不对View的onTouchEvent的Action_Down事件进行拦截.

当Layout的onInterceptTouchEvent的Action_Down返回true时,View的onTouchEvent监控不到任何事件;



事例如下:

ChildView.java(利用Action_Down返回true诱使后面的事件在无拦截的情况下被调用)

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.v("aa","ChildView::::ACTION_DOWN");
			return true; 
		case MotionEvent.ACTION_MOVE:
			Log.v("aa","ChildView::::ACTION_MOVE"); 
			break;
		case MotionEvent.ACTION_UP:
			Log.v("aa","ChildView::::ACTION_UP");
			break;
		default:
			break;
		}
		return super.onTouchEvent(event);
	}

Layout.java

@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.v("aa","Layout::::ACTION_DOWN");
			return true;
		case MotionEvent.ACTION_MOVE:
			Log.v("aa","Layout::::ACTION_MOVE");
			return true;
		case MotionEvent.ACTION_UP:
			Log.v("aa","Layout::::ACTION_UP");
			break;
		default:
			break;
		} 
		return super.onTouchEvent(event);
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.v("aa","Layout::onInterceptTouchEvent::ACTION_DOWN");
//			return true;
			break;
		case MotionEvent.ACTION_MOVE:
			Log.v("aa","Layout::onInterceptTouchEvent::ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.v("aa","Layout::onInterceptTouchEvent::ACTION_UP");
			break;
		default:
			break;
		} 
		return super.onInterceptTouchEvent(ev);
	}

运行如下:::


由上可知:当onInterceptTouchEvent拦截down为false的时候.ChildView的down被调用 并返回true,此时不向外传递 因此Layout的onTouchEvent的down没被调用.

修改onInterceptTouchEvent:

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.v("aa","Layout::onInterceptTouchEvent::ACTION_DOWN");
			return true;
//			break;
		case MotionEvent.ACTION_MOVE:
			Log.v("aa","Layout::onInterceptTouchEvent::ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			Log.v("aa","Layout::onInterceptTouchEvent::ACTION_UP");
			break;
		default:
			break;
		} 
		return super.onInterceptTouchEvent(ev);
	}
运行如下:::

也就是,当它返回true的时候,对子布局进行拦截后,执行自己的onTouchEvent();同样Action_Down返回true,后续事件如Move,Up可运行;


至此,从onInterceptTouchEvent,onTouchEvent得出3条结论:

1.onTouchEvent由内向外传递,当Action_Down返回false的时候,表示向外声明自己不能解决 由外层再处理;同理,true表示自己已经有能力处理.不需要向外传递事件(此规律适用View,ViewGroup)

2.onTouchEvent只有当当Action_Down返回true的时候的时候(同时没被事件拦截)才会执行下续的MOVE,UP

3.onInterceptTouchEvent只有ViewGroup才有,在onTouchEvent前执行,无论是任何action,只有返回false(默认)的时候,才会传递事件给子控件,如果返回false.则屏蔽了子View的事件处理 ,从该层的onTouchEvent开始处理起;



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics