现在的位置: 首页 > 综合 > 正文

Android Touch事件传递机制

2013年08月20日 ⁄ 综合 ⁄ 共 4715字 ⁄ 字号 评论关闭

MainActivity如下:

package cn.c;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
//第一次测试
//输出结果如下:
//MyFrameLayout 中调用 onInterceptTouchEvent()
//MyFrameLayout 中 onInterceptTouchEvent() 默认返回的是:false
//自定义Button 中调用 onTouchEvent()
//自定义Button 中 onTouchEvent() 默认返回的是:true
//自定义Button 中onTouchEvent()--->ACTION_DOWN
//MyFrameLayout 中调用 onInterceptTouchEvent()
//MyFrameLayout 中 onInterceptTouchEvent() 默认返回的是:false
//自定义Button 中调用 onTouchEvent()
//自定义Button 中 onTouchEvent() 默认返回的是:true
//自定义Button 中onTouchEvent()--->ACTION_UP
//小结:
//1 这是快速点击一下自定义按钮后的输出,可知:
//  Button中onTouchEvent()的ACTION_DOWN
//  和ACTION_UP前都会去调用onInterceptTouchEvent()
//
//2 如果按的时间较长那么在ACTION_DOWN和ACTION_UP
//  之间会反复执行以下代码:
//  MyFrameLayout 中调用 onInterceptTouchEvent()
//  MyFrameLayout 中 onInterceptTouchEvent() 默认返回的是:false
//  自定义Button 中调用 onTouchEvent()
//  自定义Button 中 onTouchEvent() 默认返回的是:true

//3 从此可以看出:
//  onInterceptTouchEvent() 默认返回的是:false
//  即没有拦截.
//  自定义Button的onTouchEvent()默认返回为:true
//  即可响应点击事件

//4 小梳理:因为没有拦截,所以自定义Button响应了onTouchEvent()
//  所以在MyFrameLayout中没有响应onTouchEvent()

//  第二次测试
//  onInterceptTouchEvent(MotionEvent ev)返回true
//  即拦截
//  此时自定义Button不会响应onTouchEvent()
//  但此时MyFrameLayout中会响应onTouchEvent()
//  但是只响应了ACTION_DOWN没有响应ACTION_UP
//  因为在MyFrameLayout中的onTouchEvent()默认返回false
//  若要让MyFrameLayout中响应onTouchEvent()且执行
//  ACTION_DOWN和ACTION_UP.那么需要将MyFrameLayout中
//  的onTouchEvent()返回true

// 第三次测试
// 让MyFrameLayout中 onInterceptTouchEvent()返回false(默认)
// 且让自定义Button中的onTouchEvent()返回false
// 此时的执行情况是:自定义Button中的onTouchEvent()只执行ACTION_DOWN
// 不会执行Button中的onTouchEvent()的ACTION_UP.紧接着又里面
// 执行了MyFrameLayout中的onTouchEvent()且也只响应了ACTION_DOWN.
// 为什么:MyFrameLayout中的onTouchEvent()只响应了ACTION_DOWN???
// 还是前面提到的:MyFrameLayout中的onTouchEvent()默认返回false
// 若将其返回值改为true,那么MyFrameLayout中的onTouchEvent()中的
// ACTION_DOWN和ACTION_UP都会执行.

// 综上测试总结:
// 1 MyFrameLayout中onInterceptTouchEvent()默认返回false
//   即不拦截,这样方便将点击事件传递给View中的onTouchEvent()
// 2 MyFrameLayout中的onTouchEvent()默认返回的是false
// 3 自定义View中的onTouchEvent()默认返回的是true,以便多次
//   响应OnTouch()事件
// 参考资料:
// http://blog.csdn.net/psh24053/article/details/7523486
// http://blog.csdn.net/android_tutor/article/details/7193090
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

MyFrameLayout如下:

package cn.c;

import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.FrameLayout;

public class MyFrameLayout extends FrameLayout{
	public MyFrameLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		// TODO Auto-generated method stub
		return super.dispatchKeyEvent(event);
	}
	//覆写自ViewGroup
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		System.out.println("MyFrameLayout 中调用 onInterceptTouchEvent()");
		System.out.println("MyFrameLayout 中 onInterceptTouchEvent() 默认返回的是:"+
		super.onInterceptTouchEvent(ev));
		//以下一句对应于第一次测试
		return super.onInterceptTouchEvent(ev);
		//以下一句对应于第二次测试
		//return true;
		//以下一句对应于第三次测试
		//return super.onInterceptTouchEvent(ev);
	}
	//覆写自View
	//但ViewGroup是View的子类
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		//以下对于第二次测试
		System.out.println("MyFrameLayout 中调用 onTouchEvent()");
		System.out.println("MyFrameLayout 中 onTouchEvent() 默认返回的是:"+
		super.onInterceptTouchEvent(event));
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
		System.out.println("MyFrameLayout 中onTouchEvent()--->ACTION_DOWN");
			break;
        case MotionEvent.ACTION_UP:
        System.out.println("MyFrameLayout 中onTouchEvent()--->ACTION_UP");	
		default:
			break;
		}
		return super.onTouchEvent(event);
	}
	

}

MyButton如下:

package cn.c;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;

public class MyButton extends Button{
	public MyButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		System.out.println("自定义Button 中调用 onTouchEvent()");
		System.out.println("自定义Button 中 onTouchEvent() 默认返回的是:"+super.onTouchEvent(event));
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
		System.out.println("自定义Button 中onTouchEvent()--->ACTION_DOWN");
			break;
        case MotionEvent.ACTION_UP:
        System.out.println("自定义Button 中onTouchEvent()--->ACTION_UP");	
		default:
			break;
		}
		//以下一句对应于第一,二次测试
		return super.onTouchEvent(event);
		//以下一句对应于第三次测试
		//return false;
	}
	
}

main.xml如下:

<!-- 自定义布局中,放置一个自定义控件 -->
<cn.c.MyFrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

   <cn.c.MyButton
    android:layout_width="200dip"
    android:layout_height="200dip"
    android:text="自定义Button"
    android:textColor="@android:color/black"
   />

</cn.c.MyFrameLayout>

 

抱歉!评论已关闭.