还是以自定义的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. 500lines项目简介

    "500行或更少" "What I cannot create, I do not understand." -- Richard Feynman <50 ...

  2. LR12.53—使用HP网络导游示例应用程序

    本教程使用 的HP Web之旅,一个样本的基于Web的旅行社系统,向人们展示LoadRunner将如何作为负载测试解决方案.惠普网络旅游用户连接到Web服务器,搜索航班,预订机票,检查飞行路线. 虽然 ...

  3. linux pam 控制模式

    工作类别(type).流程栈(stack)和控制模式(control) Linux-PAM 工作的"类别"(type) PAM 的具体工作主要有以下四种类别(type):accou ...

  4. click 事件 arguments.callee 每次点击自动* 2

    今天在测试JQUERY(版本3.0,向下兼容3.0)时发现一个很特别的现象,代码如下: $($('button').get(4)).click(function(){ alert($(this).ht ...

  5. 64位系统如何导入excel

    1.运行C:\Windows\SysWOW64\odbcad32.exe,打开后如下图所示: 2.点击添加,选择如下图所示Microsoft Excel Driver(*.xls) 3.点击完成,在弹 ...

  6. Android启动标记

    1. Task是包含一系列Activity的堆栈, 遵循先进后出原则. 2. Task默认行为: (1) 前提: Activity A和Activity B在同一个应用中. 操作: Activity ...

  7. IS A 和 HAS A的区别

    IS A:一般是用作继承或者接口类.比如:中国人和外国人都是人,重点在:是一个... . HAS A:一般用作对象和他的成员的从属关系.比如:中国人和外国人都有眼睛.耳朵.嘴巴.重点在:有一个... ...

  8. 填坑*** WARNING L15: MULTIPLE CALL TO SEGMENT

    填坑*** WARNING L15: MULTIPLE CALL TO SEGMENT 警告:发生了重入! 解释:在主循环里调用了一个函数,而在中断服务中又一次调用了同样的函数.当主循环运行到该函数中 ...

  9. MySQL追踪优化器小试

    首先看一下MySQL追踪优化器的典型用法: 打开:SET optimizer_trace="enabled=on"; 查询优化器的信息:SELECT * FROM INFORMAT ...

  10. [小哥Allegro72讲速成视频]

    http://v.qq.com/vplus/df932a993679cf80a0b6c87bb849e22c 第01讲 Allegro常用组件介绍 视频链接:http://v.qq.com/boke/ ...