关闭

android中onInterceptTouchEvent()方法详解

标签: Android开发
247人阅读 评论(0) 收藏 举报
分类:

这个方法其实以前不怎么关注,后来自定义布局用的多了,发现很多时候都必须要重载这个函数,  


一般重载这个函数地方就是你自定义了一个布局,extends LinearLayout等等布局


一般除了自己的业务处理外,返回值只有两种,

第一种:让父类去处理  返回值,跟踪android源码你会知道返回的是false

作用:让自定义布局上面的所有子view 例如button imageview 等可以被点击

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			downX = (int) ev.getX();
			downY = (int) ev.getY();
			windowX = (int) ev.getX();
			windowY = (int) ev.getY();
			setOnItemClickListener(ev);
		}
		return super.onInterceptTouchEvent(ev);
	}

第二种:直接返回true

作用:让自定义布局上面的所有子view不可以被点击

    @Override  
    public boolean onInterceptTouchEvent(MotionEvent ev) {  
        return true;  
    }

关于这个函数的验证我觉得借用大牛的比较好,如果你想确认这个过程的话,自己再敲一遍,很快就搞定了,我已经搞过

地址:http://blog.csdn.net/vipzjyno1/article/details/21746311

首先我们来自定义一个布局,命名为MyLayout,继承自LinearLayout,如下所示:

[java] view plaincopy
  1. public class MyLayout extends LinearLayout {  
  2.   
  3.     public MyLayout(Context context, AttributeSet attrs) {  
  4.         super(context, attrs);  
  5.     }  
  6.   
  7. }  

然后,打开主布局文件activity_main.xml,在其中加入我们自定义的布局:

[html] view plaincopy
  1. <com.example.viewgrouptouchevent.MyLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:id="@+id/my_layout"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <Button  
  9.         android:id="@+id/button1"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:text="Button1" />  
  13.   
  14.     <Button  
  15.         android:id="@+id/button2"  
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:text="Button2" />  
  19.   
  20. </com.example.viewgrouptouchevent.MyLayout>  
可以看到,我们在MyLayout中添加了两个按钮,接着在MainActivity中为这两个按钮和MyLayout都注册了监听事件:
[java] view plaincopy
  1. myLayout.setOnTouchListener(new OnTouchListener() {  
  2.     @Override  
  3.     public boolean onTouch(View v, MotionEvent event) {  
  4.         Log.d("TAG""myLayout on touch");  
  5.         return false;  
  6.     }  
  7. });  
  8. button1.setOnClickListener(new OnClickListener() {  
  9.     @Override  
  10.     public void onClick(View v) {  
  11.         Log.d("TAG""You clicked button1");  
  12.     }  
  13. });  
  14. button2.setOnClickListener(new OnClickListener() {  
  15.     @Override  
  16.     public void onClick(View v) {  
  17.         Log.d("TAG""You clicked button2");  
  18.     }  
  19. });  
我们在MyLayout的onTouch方法,和Button1、Button2的onClick方法中都打印了一句话。现在运行一下项目,效果图如下所示:

                                      

分别点击一下Button1、Button2和空白区域,打印结果如下所示:


你会发现,当点击按钮的时候,MyLayout注册的onTouch方法并不会执行,只有点击空白区域的时候才会执行该方法。你可以先理解成Button的onClick方法将事件消费掉了,因此事件不会再继续向下传递。

那就说明Android中的touch事件是先传递到View,再传递到ViewGroup的?现在下结论还未免过早了,让我们再来做一个实验。

查阅文档可以看到,ViewGroup中有一个onInterceptTouchEvent方法,我们来看一下这个方法的源码:

[java] view plaincopy
  1. /** 
  2.  * Implement this method to intercept all touch screen motion events.  This 
  3.  * allows you to watch events as they are dispatched to your children, and 
  4.  * take ownership of the current gesture at any point. 
  5.  * 
  6.  * <p>Using this function takes some care, as it has a fairly complicated 
  7.  * interaction with {@link View#onTouchEvent(MotionEvent) 
  8.  * View.onTouchEvent(MotionEvent)}, and using it requires implementing 
  9.  * that method as well as this one in the correct way.  Events will be 
  10.  * received in the following order: 
  11.  * 
  12.  * <ol> 
  13.  * <li> You will receive the down event here. 
  14.  * <li> The down event will be handled either by a child of this view 
  15.  * group, or given to your own onTouchEvent() method to handle; this means 
  16.  * you should implement onTouchEvent() to return true, so you will 
  17.  * continue to see the rest of the gesture (instead of looking for 
  18.  * a parent view to handle it).  Also, by returning true from 
  19.  * onTouchEvent(), you will not receive any following 
  20.  * events in onInterceptTouchEvent() and all touch processing must 
  21.  * happen in onTouchEvent() like normal. 
  22.  * <li> For as long as you return false from this function, each following 
  23.  * event (up to and including the final up) will be delivered first here 
  24.  * and then to the target's onTouchEvent(). 
  25.  * <li> If you return true from here, you will not receive any 
  26.  * following events: the target view will receive the same event but 
  27.  * with the action {@link MotionEvent#ACTION_CANCEL}, and all further 
  28.  * events will be delivered to your onTouchEvent() method and no longer 
  29.  * appear here. 
  30.  * </ol> 
  31.  * 
  32.  * @param ev The motion event being dispatched down the hierarchy. 
  33.  * @return Return true to steal motion events from the children and have 
  34.  * them dispatched to this ViewGroup through onTouchEvent(). 
  35.  * The current target will receive an ACTION_CANCEL event, and no further 
  36.  * messages will be delivered here. 
  37.  */  
  38. public boolean onInterceptTouchEvent(MotionEvent ev) {  
  39.     return false;  
  40. }  
如果不看源码你还真可能被这注释吓到了,这么长的英文注释看得头都大了。可是源码竟然如此简单!只有一行代码,返回了一个false!

好吧,既然是布尔型的返回,那么只有两种可能,我们在MyLayout中重写这个方法,然后返回一个true试试,代码如下所示:

[java] view plaincopy
  1. public class MyLayout extends LinearLayout {  
  2.   
  3.     public MyLayout(Context context, AttributeSet attrs) {  
  4.         super(context, attrs);  
  5.     }  
  6.       
  7.     @Override  
  8.     public boolean onInterceptTouchEvent(MotionEvent ev) {  
  9.         return true;  
  10.     }  
  11.       
  12. }  
现在再次运行项目,然后分别Button1、Button2和空白区域,打印结果如下所示:


你会发现,不管你点击哪里,永远都只会触发MyLayout的touch事件了,按钮的点击事件完全被屏蔽掉了!


看到这里,我相信你对这个函数应该已经的差不多了,

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:322942次
    • 积分:6617
    • 等级:
    • 排名:第3778名
    • 原创:261篇
    • 转载:195篇
    • 译文:61篇
    • 评论:39条
    HTML5游戏学习
    学习HTML5游戏编程
    最新评论