Android View的onTouchEvent和OnTouch区别
还是以自定义的TestButton为例。
我们可以通过重写onTouchEvent方法来处理诸如down move up的消息:
- public class TestButton extends Button {
- public TestButton(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- }
- public TestButton(Context context, AttributeSet attributeSet) {
- super(context, attributeSet);
- // TODO Auto-generated constructor stub
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- boolean value = super.onTouchEvent(event);
- System.out.println("super.onTouchEvent: " + value+ " event: " + event.getAction());
- return value;
- }

public class TestButton extends Button {
public TestButton(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public TestButton(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean value = super.onTouchEvent(event);
System.out.println("super.onTouchEvent: " + value+ " event: " + event.getAction());
return value;
}
也可以通过实现OnTouchListener的接口,然后设置TestButton的onTouchListener可以达到同样的目的
- class OnTouchListenerTest implements View.OnTouchListener{
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return false;
- }
- }

class OnTouchListenerTest implements View.OnTouchListener{
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
}
- TestButton b = (TestButton)findViewById(R.id.button);
- OnTouchListenerTest listener = new OnTouchListenerTest();
- b.setOnTouchListener(listener);

TestButton b = (TestButton)findViewById(R.id.button);
OnTouchListenerTest listener = new OnTouchListenerTest();
b.setOnTouchListener(listener);
但上述两种监听有什么区别呢?
先看一下Android源码中对于View中dispatchTouchEvent的实现:
- public boolean dispatchTouchEvent(MotionEvent event){
- ... ...
- if(onFilterTouchEventForSecurity(event)){
- ListenerInfo li = mListenerInfo;
- if(li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
- && li.mOnTouchListener.onTouch(this, event)) {
- return true;
- }
- if(onTouchEvent(event)){
- return true;
- }
- }
- ... ...
- return false;
- }

//源码:
public boolean dispatchTouchEvent(MotionEvent event){
... ...
if(onFilterTouchEventForSecurity(event)){
ListenerInfo li = mListenerInfo;
if(li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
return true;
}
if(onTouchEvent(event)){
return true;
}
}
... ...
return false;
}
可以看到onTouchListener的接口的优先级是要高于onTouchEvent的,假若onTouchListener中的onTouch方法返回true,
表示此次事件已经被消费了,那onTouchEvent是接收不到消息的。
因为Button的performClick是利用onTouchEvent实现,假若onTouchEvent没有被调用到,那么Button的Click事件也无法响应。
综合来讲:
onTouchListener的onTouch方法优先级比onTouchEvent高,会先触发。
假如onTouch方法返回false会接着触发onTouchEvent,反之onTouchEvent方法不会被调用。
内置诸如click事件的实现等等都基于onTouchEvent,假如onTouch返回true,这些事件将不会被触发。
//------------布局文件--------------------
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent" tools:context="myontouch.bwie.com.myontouch.MainActivity"> <myontouch.bwie.com.myontouch.TestButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击"
android:id="@+id/button"/>
</RelativeLayout> //--------------自定义TextButton--------------------------
public class TestButton extends Button{
public TestButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TestButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean value = super.onTouchEvent(event);
System.out.println("super.onTouchEvent: " + value+ " event: " + event.getAction());
Log.i("我是onTouchEvent","onTouchEvent");
return value;
}
}
//----------------主Activity-------------
public class MainActivity extends AppCompatActivity {
private TestButton button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
button = (TestButton) findViewById(R.id.button);
OnTouchListenerTest listener = new OnTouchListenerTest();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i("我是OnClickListener","OnClickListener");
}
});
button.setOnTouchListener(listener);
}
class OnTouchListenerTest implements View.OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("我是onTouch","onTouch");
return false;
}
}
//---------------下面是我的OnTouch 返回false 时,的打印----------
12-14 13:52:51.550 8752-8752/myontouch.bwie.com.myontouch I/我是onTouch: onTouch
12-14 13:52:51.553 8752-8752/myontouch.bwie.com.myontouch I/System.out: super.onTouchEvent: true event: 0
12-14 13:52:51.554 8752-8752/myontouch.bwie.com.myontouch I/我是onTouchEvent: onTouchEvent
12-14 13:52:51.565 8752-8752/myontouch.bwie.com.myontouch I/我是onTouch: onTouch
12-14 13:52:51.566 8752-8752/myontouch.bwie.com.myontouch I/System.out: super.onTouchEvent: true event: 2
12-14 13:52:51.566 8752-8752/myontouch.bwie.com.myontouch I/我是onTouchEvent: onTouchEvent
12-14 13:52:51.649 8752-8752/myontouch.bwie.com.myontouch I/我是onTouch: onTouch
12-14 13:52:51.649 8752-8752/myontouch.bwie.com.myontouch I/System.out: super.onTouchEvent: true event: 1
12-14 13:52:51.649 8752-8752/myontouch.bwie.com.myontouch I/我是onTouchEvent: onTouchEvent
12-14 13:52:51.656 8752-8752/myontouch.bwie.com.myontouch I/我是OnClickListener: OnClickListener
//-------------------下面是 onTouch 返回 true时的打印-------------------------
12-14 14:03:33.399 19886-19886/myontouch.bwie.com.myontouch I/我是onTouch: onTouch
12-14 14:03:33.415 19886-19886/myontouch.bwie.com.myontouch I/我是onTouch: onTouch
12-14 14:03:33.429 19886-19886/myontouch.bwie.com.myontouch I/我是onTouch: onTouch
Android View的onTouchEvent和OnTouch区别的更多相关文章
- Android进阶笔记19:onInterceptTouchEvent、onTouchEvent与onTouch
1.onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后, ...
- Android进阶笔记16:onInterceptTouchEvent、onTouchEvent与onTouch
1. onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后 ...
- android: View, SurfaceView, GLSurfaceView, TextureView 区别与联系
区别与联系 View: 显示视图,内置画布,提供了图形绘制函数.触屏事件.按键事件函数等,必须在UI主线程内更新画面,速度较慢: SurfaceView: 基于view视图进行拓展的视图类,更适合2D ...
- Android View的事件分发
如果接触android开发时间足够长的话,或多或少都会遇到各种各样事件冲突的问题,要想解决这类问题,对深入理解事件分发机制是很有必要的,接下来几天都会尽自己所能尽可能将这方面讲清楚. View的事件 ...
- Android View的滑动
Android View的滑动 文章目录 Android View的滑动 一.实现移动 1.1 layout() 1.2 设置位置偏移量 1.3 改变布局参数 1.4 动画 1.5 ScrollTo以 ...
- 浅谈Android View事件分发机制
引言 前面的文章介绍了View的基础知识和View的滑动,今天我们来介绍View的另一个核心知识,View的事件分发机制. 点击事件的传递规则 所谓的点击事件的分发机制,其实就是对MotionEven ...
- Android view的一些认识
转载:9102年末,我对Android view的13条认识: (顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找)https://github.com/xiangjiana/Andro ...
- Android View 事件分发机制 源码解析 (上)
一直想写事件分发机制的文章,不管咋样,也得自己研究下事件分发的源码,写出心得~ 首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个My ...
- Android View中的控件和监听方法...
PS:居然三天没写博客了...今天补上...东西虽多,但是都是一些基础...代码多了一些,有人可能会这样问,粘这么多代码有毛用..其实对于一个Android的初学者来说,一个完整的代码是最容易帮助理解 ...
随机推荐
- HandlerThread和IntentService
HandlerThread 为什么要使用HandlerThread? 我们经常使用的Handler来处理消息,其中使用Looper来对消息队列进行轮询,并且默认是发生在主线程中,这可能会引起UI线程的 ...
- 跨域访问CORS
由于现代浏览器的同源策略,合理的跨域请求也变得至关重要. CORS(Cross-Origin Resource Sharing,跨域资源共享)定义了在必须访问跨域资源时,浏览器与服务器应该如何沟通.它 ...
- Eclipse使用tomcat的原理
1. 当我们使用Eclipse将项目部署到Tomcat的时,我们发现,在Tomcat下的webapps目录下并没有我们创建好的项目,但是当通过Eclipse启动服务器后,项目却真的可以访问到,这是为什 ...
- CString转string
如题,找了半天... //CString转string USES_CONVERSION; CString temp; temp = _T("kjdsaflkjdlfkj"); ch ...
- Struts2 XML配置详解
struts官网下载地址:http://struts.apache.org/ 1. 深入Struts2的配置文件 本部分主要介绍struts.xml的常用配置. 1.1. 包配置: S ...
- 在spring框架中配置Quartz定时器发生错误: class org.springframework.scheduling.quartz.JobDetailBean has interface org.quartz.JobDetail as sup
这是由于spring和Quartz的不兼容性造成的.我的spring是4.0.2,但是Quartz是2.2.3的,换了一个1.8版本的Quartz就解决问题了.
- window SVN设置忽略文件列表
进入checkout的项目文件夹. 执行 mvn install.生成 target文件夹. 如果这时候不想让target文件夹纳入版本控制.则进入子文件夹,在target文件夹上 右键执行 查看设置 ...
- 项目在build machine中失败,本地Build成功的程序集版本问题
MSBuild在build machine中遇到which has a higher version than its reference assembly:(in my case let's say ...
- [c#]一个窗体调用另一个窗体的事件
StuAddForm a = new StuAddForm(); a.IfStudent(textBox1.Text.Trim()):
- eclipse连接外部tomcat进行debug
首先,在tomcat/bin目录下找到编辑catalina.bat,在 rem $Id: catalina.bat 1344732 2012-05-31 14:08:02Z kkolinko $rem ...