还是以自定义的TestButton为例。

我们可以通过重写onTouchEvent方法来处理诸如down move up的消息:

  1. public class TestButton extends Button {
  2. public TestButton(Context context) {
  3. super(context);
  4. // TODO Auto-generated constructor stub
  5. }
  6. public TestButton(Context context, AttributeSet attributeSet) {
  7. super(context, attributeSet);
  8. // TODO Auto-generated constructor stub
  9. }
  10. @Override
  11. public boolean onTouchEvent(MotionEvent event) {
  12. boolean value = super.onTouchEvent(event);
  13. System.out.println("super.onTouchEvent: " + value+ " event: " + event.getAction());
  14. return value;
  15. }
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可以达到同样的目的

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

但上述两种监听有什么区别呢?

先看一下Android源码中对于View中dispatchTouchEvent的实现:

  1. public boolean dispatchTouchEvent(MotionEvent event){
  2. ... ...
  3. if(onFilterTouchEventForSecurity(event)){
  4. ListenerInfo li = mListenerInfo;
  5. if(li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
  6. && li.mOnTouchListener.onTouch(this, event)) {
  7. return true;
  8. }
  9. if(onTouchEvent(event)){
  10. return true;
  11. }
  12. }
  13. ... ...
  14. return false;
  15. }
 
//源码:
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区别的更多相关文章

  1. Android进阶笔记19:onInterceptTouchEvent、onTouchEvent与onTouch

    1.onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后, ...

  2. Android进阶笔记16:onInterceptTouchEvent、onTouchEvent与onTouch

    1. onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后 ...

  3. android: View, SurfaceView, GLSurfaceView, TextureView 区别与联系

    区别与联系 View: 显示视图,内置画布,提供了图形绘制函数.触屏事件.按键事件函数等,必须在UI主线程内更新画面,速度较慢: SurfaceView: 基于view视图进行拓展的视图类,更适合2D ...

  4. Android View的事件分发

    如果接触android开发时间足够长的话,或多或少都会遇到各种各样事件冲突的问题,要想解决这类问题,对深入理解事件分发机制是很有必要的,接下来几天都会尽自己所能尽可能将这方面讲清楚.  View的事件 ...

  5. Android View的滑动

    Android View的滑动 文章目录 Android View的滑动 一.实现移动 1.1 layout() 1.2 设置位置偏移量 1.3 改变布局参数 1.4 动画 1.5 ScrollTo以 ...

  6. 浅谈Android View事件分发机制

    引言 前面的文章介绍了View的基础知识和View的滑动,今天我们来介绍View的另一个核心知识,View的事件分发机制. 点击事件的传递规则 所谓的点击事件的分发机制,其实就是对MotionEven ...

  7. Android view的一些认识

    转载:9102年末,我对Android view的13条认识: (顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找)https://github.com/xiangjiana/Andro ...

  8. Android View 事件分发机制 源码解析 (上)

    一直想写事件分发机制的文章,不管咋样,也得自己研究下事件分发的源码,写出心得~ 首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个My ...

  9. Android View中的控件和监听方法...

    PS:居然三天没写博客了...今天补上...东西虽多,但是都是一些基础...代码多了一些,有人可能会这样问,粘这么多代码有毛用..其实对于一个Android的初学者来说,一个完整的代码是最容易帮助理解 ...

随机推荐

  1. android 双击返回按钮退出程序。

    重写   onKeyDown()方法. @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == K ...

  2. log4j输出模板

    log4j.rootLogger=DEBUG, A1,A2 log4j.appender.A1.MaxFileSize=1kb#10个备份 log4j.appender.A1.MaxBackupInd ...

  3. sed命令

    sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法sed命令行格式为:         sed ...

  4. EUI HSlider 实现音量控制

    一 HSlider使用 直接拖动到exml上,并赋值默认皮肤 <?xml version="1.0" encoding="utf-8"?> < ...

  5. disconf系列【2】——解决zk部署情况为空的问题

    如下图所示,在安装完成之后,发现zk(zookeeper)部署情况为空. 注:承接上篇,环境未发生改变. 1.解决zk没有启动的问题 查看disconf日志,发现zk没有启动. 实际情况是:zk已经启 ...

  6. Kafka深入理解-1:Kafka高效的文件存储设计

    文章摘自:美团点评技术团队  Kafka文件存储机制那些事 Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日 ...

  7. 定制自己的linux系统

    算是总结式文档,以备后忘 先说一下背景,一开始我就知道有这个任务,同时我自己也非常感兴趣,打算去研究研究 于是才同意接这个任务,但是我的原意是从头开始搭建系统,也就是lfs 但接到任务后,由于种种原因 ...

  8. oracle删除users表空间

    1.users表空间一般情况下是默认的,需将别的空间设置成默认,再删除users表空间(oracle不允许删除默认空间的). 2.删除表空间的同时会报这样的错:ORA-22868错误.原因:推断应该存 ...

  9. Java面试宝典答案详解与感悟(第一天)

    一.Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法,虚拟机方面的语法. 1.一个".java&quo ...

  10. iOS 10开发NSAssert(断言)的使用

    断言(NSAssert)的使用 字数1055 阅读3270 评论3 喜欢30 NSAssert()是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属于Bug ...