欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android onTouchEvent处理机制总结(必看)

程序员文章站 2022-05-20 21:54:16
项目中总会用到一些触摸事件,每次使用都是百度各种资料,看各种大神的分析笔记。这次我自己总结下关于触摸事件的一些知识点。一来可以让自己对触摸事件印象更加深刻,也给以后的项目做...

项目中总会用到一些触摸事件,每次使用都是百度各种资料,看各种大神的分析笔记。这次我自己总结下关于触摸事件的一些知识点。一来可以让自己对触摸事件印象更加深刻,也给以后的项目做一个参考。最难理解的其实是ontouchevent方法。

一、 概述

1.只有view,viewgroup,activity 具有事件分发和消费的功能。

2.activity因为上最先接触到触摸事件,因此activity没有事件拦截方法。即没有dispatchtouchevent方法。

3.对于不能添加子控件的view,不能对事件进行分发和拦截,它只有ontouchevent事件。

二、三个方法

1.public boolean dispatchtouchevent(motionevent ev)

当触摸事件发生的时候,首先会被当前的activity进行分发,即当前activity的dispatchtouchevent方法会被执行。

这个时候,该方法有三种返回的情况:

return false: 表明事件不会被进行分发。事件会以冒泡的方式被传递给上层的view或activity的ontouchevent方法进行消费掉。

return true:表明该时间已经被处理。事件会被当前view或activity的dispatchtouchevent给消费掉。不会再进行传递,事件到此结束。

return super.dispatchtouchevent(ev):表明该事件将会被分发。此时当前view的oninterceptertouchevent方法会捕获该事件,判断需不需要进行事件的拦截。

2.public boolean onintercepttouchevent(motionevent ev)    

该方法用户拦截被传递过来的事件,用于判断被传递过来的事件是否需要被当前的view进行处理。

return false :不对事件进行拦截,放行该事件。事件会被传递到当前view的子控件中,由子控件中的dispatchtouchevent方法进行分发处理。

return true : 拦截该事件,将该事件交给当前view的ontouchevent方法进行处理。

return super.inintercepttouchevent(ev):默认拦截方式,和return true一样。该事件会被拦截,将该事件交给当前view的ontouchevent方法进行处理。(这里需要有一点说明,当有两个view。a view中有一个b view.点击a.a中如果onintercepttouchevent()返回super.intercepttouchevent(ev),则事件将会被a进行拦截,交给a的ontouchevent()进行处理,如果点击的是b,a中如果onintercepttouchevent()返回super.intercepttouchevent(ev),则事件将不会被拦截,会被分发到子控件中) 

3.public boolean ontouchevent(motionevent event)

当前的view把事件进行了拦截,则事件则会被传递到该方法中

return false:表明没有消费该事件,事件将会以冒泡的方式一直被传递到上层的view或activity中的ontouchevent事件处理。如果最上层的view或activity中的ontouchevent还是返回false。则该事件将消失。接下来来的一系列事件都将会直接被上层的ontouchevent方法捕获

return true: 表明消费了该事件,事件到此结束。

return super.ontouchevent(event):默认情况,和return false一样。

验证:

mainactivity fatherview childview中几个方法都返回super.****touchevent(ev)

分析:

1、当点击屏幕。mainactivity 中的dispatchtouchevent方法先执行,打印mainactivity-dispatchtouchevent-->action_down

2、因为返回的是super.dispatchtouchevent(ev),所以事件ev将会被分发,但是mainactivity中没有onintercepttouchevent()方法,所以事件被传递到fatherview中的dispatchtouchevent方法.打印fatherview-dispatchtouchevent-->action_down

3、在fatherview中dispatchtouchevent返回的是super.dispatchtouchevent(ev),所有事件会被分发。fatherview中的onintercepttoucheven()中的方法被执行。打印fatherview-onintercepttoucheven-->action_down

4、fatherview中的onintercepttoucheven()返回的是super.onintercepttouchevent(ev)。在这里,(1)如果点击的是屏幕中的childview。事件将不会被拦截,会被传递到childview中的dispatchtouchevent方法中。(2)如果点击的值fatherview则事件将会被拦截。fatherview中的ontouchevent()方法将被执行。以(1)为例,将打印childview-dispatchtouchevent-->action_down。

5、childview中dispatchtouchevent返回的是super.dispatchtouchevent(ev),所有事件会被分发。打印childview-onintercepttouchevent-->action_down。

6、此时childview中onintercepttouchevent返回的是super.onintercepttouchevent(ev),,而且已经没有子控件了,所以事件将被拦截。打印childview-ontouchevent-->action_down。

7、在childview中ontouchevent()返回额是super.ontouchevent(ev)。事件将不会被消耗,将以冒泡的方式传递到上层空间中的ontouchevent(),此处上层空间中的ontouchevent返回的都是super.ontouchevent(ev)。所以讲一次打印 father-ontouchevent-->action_down。 mainactivty-ontouchevent-->action_down。

8、之后的事件动作,将不再被mainactivity分发到子view,直接被mainactivty中的ontouchevent处理消耗。打印mainactivity-dispatchtouchevent-->action_up,mainactivty-ontouchevent-->action_up

mainactivity-dispatchtouchevent-->action_down
fatherview-dispatchtouchevent-->action_down
fatherview-onintercepttoucheven-->action_down
childview-dispatchtouchevent-->action_down
childview-onintercepttouchevent-->action_down。
childview-ontouchevent-->action_down
father-ontouchevent-->action_down。 
mainactivty-ontouchevent-->action_down
mainactivity-dispatchtouchevent-->action_up,
mainactivty-ontouchevent-->action_up

代码

mainactivity.java

public class mainactivity extends activity {
 
  private static final string tag = "mainactivity";
 
  @override
  protected void oncreate(bundle savedinstancestate) {
   super.oncreate( savedinstancestate);
   setcontentview(r.layout. activity_main);
  }
 
  @override
  public boolean ontouchevent(motionevent event) {
   // todo auto-generated method stub
   log. i(tag, "activity-ontouchevent-->" + toucheventutil.gettouchaction(event.getaction()));
   return super.ontouchevent( event);
  }
 
  @override
  public boolean dispatchtouchevent(motionevent ev) {
   log. i(tag, "activity-dispatchtouchevent-->" + toucheventutil.gettouchaction(ev.getaction()));
   return super.dispatchtouchevent( ev);
  }
fatherview.java
public class fatherview extends linearlayout {
  private static final string tag = "mainactivity";
 
  public fatherview(context context) {
   super( context);
 
  }
 
  @override
  public boolean dispatchtouchevent(motionevent ev) {
   log. i(tag, "father-dispatchtouchevent-->" + toucheventutil.gettouchaction(ev.getaction()));
   return super.dispatchtouchevent( ev);
  }
 
  @override
  public boolean onintercepttouchevent(motionevent ev) {
   log. i(tag, "father-onintercepttouchevent-->" + toucheventutil.gettouchaction(ev.getaction()));
   return super.onintercepttouchevent( ev);
  }
 
  @override
  public boolean ontouchevent(motionevent event ) {
   log. i(tag, "father-ontouchevent-->" + toucheventutil.gettouchaction(event.getaction()));
   return super.ontouchevent( event);
  }
 
}
childview.java
public class childview extends linearlayout {
 
  private static final string tag = "mainactivity";
 
  public childview(context context) {
   super( context);
  }
 
  @override
  public boolean dispatchtouchevent(motionevent ev) {
   log. i(tag, "child-dispatchtouchevent-->" + toucheventutil.gettouchaction(ev.getaction()));
   return super.dispatchtouchevent( ev);
  }
 
  @override
  public boolean onintercepttouchevent(motionevent ev) {
   log. i(tag, "child-onintercepttouchevent-->" + toucheventutil.gettouchaction(ev.getaction()));
   return super.onintercepttouchevent( ev);
  }
 
  @override
  public boolean ontouchevent(motionevent event ) {
   log. i(tag, "child-ontouchevent-->" + toucheventutil.gettouchaction(event.getaction()));
   return super.ontouchevent( event);
  }
 
}
 

activity_main.xml

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width= "match_parent"
 android:layout_height= "match_parent"
 tools:context="${relativepackage}.${activityclass}" >
 
 <com.ethanlbb.toucheventtest.fatherview
  android:layout_width= "match_parent"
  android:layout_height= "match_parent"
  android:background= "@android:color/holo_blue_dark"
  android:gravity= "center" >
 
  <com.ethanlbb.toucheventtest.childview
   android:layout_width= "200dp"
   android:layout_height= "200dp"
   android:layout_gravity= "center"
   android:background= "#0000ff" >
  </com.ethanlbb.toucheventtest.childview >
 </com.ethanlbb.toucheventtest.fatherview >
 
</relativelayout>

以上这篇android ontouchevent处理机制总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。