`
king_tt
  • 浏览: 2119528 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

详解onInterceptTouchEvent和onTouchEvent之间的关系

阅读更多

过完今天就放假了,哇哈哈,提前祝大家端午快乐,多吃粽子,公司给我们发了几个粽子,今天早上吃了个,还不错,呵呵,回到正题...之前在网上看了很多这方面的文章,有的写得很不错,然后我也决定自己也写一篇这样子的文章,一是加深理解onInterceptTouchEvent和onTouchEvent之间的关系,二是希望大家看到我写得东西能少走些弯路,本人的语文也不是很好,语文是数学老师教的,每次写文章也是跟着感觉走,呵呵

1.onInterceptTouchEvent(),Intercept 阻断,打断的意思,顾名思义这个方法是阻断TouchEvent的传递,这个方法返回值是false或者true,也许很多不了解的人就会问,阻断TouchEvent的传递是什么意思?onInterceptTouchEvent()这个方法是ViewGroup里面的方法,一个ViewGroup里面可以包含很多的ViewGroup、View,然后ViewGroup里面的View想要获得TouchEvent的话,必须是从ViewGroup传递过来的,而onInterceptTouchEvent方法就是拦截TouchEvent的,顾名思义,当onInterceptTouchEvent返回false的时候,子View就有TouchEvent,返回true的时候,子View的TouchEvent就被拦截了,TouchEvent就给ViewGroup处理,子View就没有TouchEvent

2.onTouchEvent()用于处理事件(重点onTouch这个事件是从子控件回传到父控件的,一层层向上传),返回值决定当前控件是否消费(consume)了这个事件,也就是说在当前控件在处理完Touch事件后,是否还允许Touch事件继续向上(父控件)传递。
返回false,则向上传递给父控件,详细一点就是这个touch事件就给了父控件,那么后面的up事件就是到这里touch触发,不会在传给它的子控件。如果父控件依然是false,那touch的处理就给到父控件的父控件,那么up的事件处理都在父控件的父控件,不会触发下面的。
返回true,如果是子控件返回true,那么它的touch事件都在这里处理,父控件是处理不了,因为它收不到子控件传给他的touch,被子控件给拦截了
(注:可能你会觉得是否消费了有关系吗,反正我已经针对事件编写了处理代码?答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。)

下面我们结合例子来深刻理解下这两者之间的关系

1.首先我们新建一个MyLayout继承LinearLayout,我们知道onInterceptTouchEvent()是ViewGroup里面的方法,我们不直接去继承ViewGroup而是继承ViewGroup的一个导出类(子类),然后重写onInterceptTouchEvent和onTouchEvent这两个方法,onInterceptTouchEvent默认情况下返回false,即不拦截TouchEvent,onTouchEvent默认返回false,即ViewGroup默认不消费TouchEvent

 

package com.example.ontouchactivity;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyLayout extends LinearLayout {
	private static final String TAG = "OnTouch";

	public MyLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		Log.e(TAG, "MyLayout----onInterceptTouchEvent");
		return super.onInterceptTouchEvent(ev);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.e(TAG, "MyLayout----DOWN");
			break;
		case MotionEvent.ACTION_UP:
			Log.e(TAG, "MyLayout----UP");
			break;
		}
		return super.onTouchEvent(event);
	}
}

 

然后布局文件,在MyLayout里面嵌套一个TextView

 

 <com.example.ontouchactivity.MyLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent" >
     
     <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world" />

 </com.example.ontouchactivity.MyLayout>

MainActivity如下

 

 

package com.example.ontouchactivity;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.TextView;

public class MainActivity extends Activity {
	private static final String TAG = "OnTouch";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		TextView mTextView = (TextView) findViewById(R.id.text);
		mTextView.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					Log.i(TAG, "TextView----DOWN");
					break;
				case MotionEvent.ACTION_UP:
					Log.i(TAG, "TextView----UP");
					break;
				}
				return false;
			}
		});
	}


}

1.默认情况下,我们触摸下屏幕看下打印

 


传递顺序:MyLayout---->TextView----->MyLayout,因为onInterceptTouchEvent默认情况下返回false,即不拦截TouchEvent,所以将TouchEvent传递给TextView,而TextView返回false,即没有消费TouchEvent,没有消费就将TouchEvent向上传递给MyLayout,而MyLayout的onTouchEvent默认情况下返回是false,即也是不消费TouchEvent,所以我们看到如上的打印

2.将MyLayout的onInterceptTouchEvent返回值修改为true,拦截TouchEvent,看下打印输出


传递顺序:MyLayout----->MyLayout,我们看到TouchEvent并没有传递给TextView,而是被MyLayout给拦截了,拦截之后MyLayout会将TouchEvent传给自己,

MyLayout的onTouchEvent默认情况下返回是false,即不消费TouchEvent,所以我们看到如上的打印

3.将MyLayout的onInterceptTouchEvent返回值修改为true,拦截TouchEvent,将MyLayout的onTouchEvent返回值修改为true看下打印输出


传递顺序:MyLayout----->MyLayout---->MyLayoutTouchEvent被MyLayout给拦截了,TouchEvent传递给自己,而onTouchEvent返回值为true,即自己消费TouchEvent,所以我们看到如上的打印

4.将MyLayout的onInterceptTouchEvent返回值修改为false,将TextView的Ontouch的返回值修改为true, MyLayout的onTouchEvent返回值false 或者 true 都无所谓,看下打印输出


传递顺序:按下MyLayout----->TextView,抬起MyLayout----->TextView,因为按下时MyLayout将TouchEvent传递给TextView,而TextView返回true,消费了TouchEvent,消费了TouchEvent就不向上传给MyLayout了,抬起也是一样

大概就是这个意思,不知道按照我思路写的文章大家看不看得懂,呵呵,写的有错误的地方还希望大家指出,谢谢

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics