Android事件模型之interceptTouchEvnet ,onTouchEvent关系正解
参考文档:
http://blog.csdn.net/liutao5757124/article/details/6097125
首先,看Android的官方文档正解
onInterceptTouchEvent()与onTouchEvent()的机制:
1. down事件首先会传递到onInterceptTouchEvent()方法
2. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,
那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最
终的目标view的onTouchEvent()处理
3. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,
那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样
传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。
4. 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一
层次的view的onTouchEvent()处理
5. 如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递
给该view的onTouchEvent()处理
这是官方文档的说法,要是自己没亲自去写个程序观察哈,基本上没法理解,所以上程序先,然后分析:
布局文件main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.hao.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.hao.LayoutView2
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:gravity="center">
<com.hao.MyTextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="@+id/tv" android:text="AB" android:textSize="40sp"
android:textStyle="bold" android:background="#FFFFFF"
android:textColor="#0000FF" />
</com.hao.LayoutView2>
</com.hao.LayoutView1>
第一层自定义布局LayoutView1.java
package com.hao;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;
public class LayoutView1 extends LinearLayout {
private final String TAG = "LayoutView1";
public LayoutView1(Context context, AttributeSet attrs) {
super(context, attrs);
Log.e(TAG,TAG);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"onInterceptTouchEvent action:ACTION_DOWN");
// return true; 在这就拦截了,后面的就不会得到事件
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG,"onInterceptTouchEvent action:ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"onInterceptTouchEvent action:ACTION_UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(TAG,"onInterceptTouchEvent action:ACTION_CANCEL");
break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"onTouchEvent action:ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG,"onTouchEvent action:ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"onTouchEvent action:ACTION_UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");
break;
}
return true;
// return false;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
第二层布局LayoutView2.java
package com.hao;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;
public class LayoutView2 extends LinearLayout {
private final String TAG = "LayoutView2";
public LayoutView2(Context context, AttributeSet attrs) {
super(context, attrs);
Log.e(TAG,TAG);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"onInterceptTouchEvent action:ACTION_DOWN");
// return true;
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG,"onInterceptTouchEvent action:ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"onInterceptTouchEvent action:ACTION_UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(TAG,"onInterceptTouchEvent action:ACTION_CANCEL");
break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"onTouchEvent action:ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG,"onTouchEvent action:ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"onTouchEvent action:ACTION_UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");
break;
}
// return true;
return false;
}
}
自定义MyTextView.java
package com.hao;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class MyTextView extends TextView {
private final String TAG = "MyTextView";
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
Log.e(TAG,TAG);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"onTouchEvent action:ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG,"onTouchEvent action:ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"onTouchEvent action:ACTION_UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");
break;
}
return false;
// return true;
}
public void onClick(View v) {
Log.e(TAG, "onClick");
}
public boolean onLongClick(View v) {
Log.e(TAG, "onLongClick");
return false;
}
}
其实代码很简单,就是自定义了View,在View里面都重写了interceptTouchEvnet (),和onTouchEvent(),然后测试其返回值,对监听的影响,关键是自己动手,逐个测试,并预测结果,等你能预测结果的时候,也就懂了,需要修改的地方就是interceptTouchEvnet 和onTouchEvent的返回值,他们决定了事件监听的流程,下面我画了一张图,如有不足之处欢迎指正,谢谢!
下面是我的正解:
下附源代码:
上一篇: jQuery 事件模型【2】
下一篇: 爆笑的体检、吵架和泡妞。