MainActivity如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package cn.c;
import android.os.Bundle;
import android.app.Activity;
import android.view.MotionEvent;
 
/**
 * Demo描述:
 * 分析Android事件分发和处理机制
 *
 * 在该示例中涉及到三个自定义的View.分别是:
 * 最外层的布局MyFrameLayout
 * 内层的布局MyLinearLayout
 * 最里层的自定义按钮MyButton
 *
 * 在dispatchTouchEvent()源码分析中提到一个很重要的东西:
 * 如果一个View没有处理ACTION_DOWN事件,即对于该事件返回了false(没有消费该事件)
 * 那么后续的ACTION_MOVE和ACTION_UP均不会再传递到该View;也就是说该View没有了
 * 处理ACTION_MOVE和ACTION_UP的资格.
 * 对于该问题,在此予以验证.
 *
 *
 * MyButton的onTouchEvent()方法中直接返回false.
 * 那么可以看到MyButton只处理了ACTION_DOWN.
 * 类似的MyFrameLayout和MyLinearLayout对于Touch事件也直接返回了false;他们也就处理不到
 * ACTION_MOVE和ACTION_UP
 *
 */
 
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        System.out.println(===> MainActivity 中调用 onCreate());
        System.out.println(--------------------------------------------------);
    }
     
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        System.out.println(===> MainActivity 中调用 dispatchTouchEvent());
        System.out.println(===> super.dispatchTouchEvent()默认返回true);
        System.out.println(--------------------------------------------------);
        return super.dispatchTouchEvent(ev);
    }
 
    @Override
    public void onUserInteraction() {
        System.out.println(===> MainActivity 中调用 onUserInteraction());
        System.out.println(--------------------------------------------------);
        super.onUserInteraction();
    }
     
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println(===> MainActivity 中调用  onTouchEvent()--->ACTION_DOWN);
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println(===> MainActivity 中调用  onTouchEvent()--->ACTION_MOVE);
            break;
        case MotionEvent.ACTION_UP:
            System.out.println(===> MainActivity 中调用  onTouchEvent()--->ACTION_UP);
        default:
            break;
        }
        System.out.println(super.onTouchEvent()默认返回false 表示未消费事件);
        System.out.println(--------------------------------------------------);
        return super.onTouchEvent(event);
    }
     
}

MyFrameLayout如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package cn.c;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;
 
public class MyFrameLayout extends FrameLayout{
    public MyFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        super.dispatchTouchEvent(ev);
        System.out.println(外层MyFrameLayout 中调用  dispatchTouchEvent());
        System.out.println(super.dispatchTouchEvent()默认返回true 表示继续分发);
        System.out.println(--------------------------------------------------);
        return super.dispatchTouchEvent(ev);
        //return false;
    }
     
    //覆写自ViewGroup
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        System.out.println(外层MyFrameLayout 中调用  onInterceptTouchEvent());
        System.out.println(super.onInterceptTouchEvent()默认返回false 表示不拦截);
        System.out.println(--------------------------------------------------);
        return super.onInterceptTouchEvent(ev);
    }
    //注意:
    //1 ViewGroup是View的子类
    //2 ViewGroup中onTouchEvent()方法默认返回的是false
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println(外层MyFrameLayout 中调用  onTouchEvent()--->ACTION_DOWN);
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println(外层MyFrameLayout 中调用  onTouchEvent()--->ACTION_MOVE);
            break;
        case MotionEvent.ACTION_UP:
            System.out.println(外层MyFrameLayout 中调用  onTouchEvent()--->ACTION_UP);
        default:
            break;
        }
        System.out.println(super.onTouchEvent()默认返回false 表示未消费事件);
        System.out.println(--------------------------------------------------);
        return super.onTouchEvent(event);
        //return true;
    }
     
     
 
}

MyLinearLayout如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package cn.c;
 
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;
 
public class MyLinearLayout extends LinearLayout {
    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
     
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        super.dispatchTouchEvent(ev);
        System.out.println(内层MyLinearLayout 中调用  dispatchTouchEvent());
        System.out.println(super.dispatchTouchEvent()默认返回true 表示继续分发);
        System.out.println(--------------------------------------------------);
        return super.dispatchTouchEvent(ev);
        //return false;
    }
     
    //覆写自ViewGroup
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        super.onInterceptTouchEvent(ev);
        System.out.println(内层MyLinearLayout 中调用  onInterceptTouchEvent());
        System.out.println(super.onInterceptTouchEvent()默认返回false 表示不拦截);
        System.out.println(--------------------------------------------------);
        return super.onInterceptTouchEvent(ev);
         
    }
    //注意:
    //1 ViewGroup是View的子类
    //2 ViewGroup中onTouchEvent()方法默认返回的是false
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println(内层MyLinearLayout 中调用  onTouchEvent()--->ACTION_DOWN);
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println(内层MyLinearLayout 中调用  onTouchEvent()--->ACTION_MOVE);
            break;
        case MotionEvent.ACTION_UP:
            System.out.println(内层MyLinearLayout 中调用  onTouchEvent()--->ACTION_UP);
        default:
            break;
        }
        System.out.println(super.onTouchEvent()默认返回false 表示未消费事件);
        System.out.println(--------------------------------------------------);
        return super.onTouchEvent(event);
    }
     
     
 
}

MyButton如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package cn.c;
 
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;
 
public class MyButton extends Button{
    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
     
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        System.out.println(自定义Button 中调用 dispatchTouchEvent());
        System.out.println(super.dispatchTouchEvent默认返回true);
        System.out.println(--------------------------------------------------);
        return super.dispatchTouchEvent(event);
    }
     
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println(自定义Button 中调用 onTouchEvent()--->ACTION_DOWN);
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println(自定义Button 中调用 onTouchEvent()--->ACTION_MOVE);
            break;
        case MotionEvent.ACTION_UP:
            System.out.println(自定义Button 中调用 onTouchEvent()--->ACTION_UP);
            break;
        default:
            break;
        }
        System.out.println(--------------------------------------------------);
        //return false;
        return true;
    }
     
     
}
1
2
3
4
5
<cn.c.myframelayout android:layout_height="fill_parent" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
    <cn.c.mylinearlayout android:layout_height="wrap_content" android:layout_width="wrap_content">
           <cn.c.mybutton android:layout_height="200dip" android:layout_width="200dip" android:text="自定义Button" android:textcolor="@android:color/black">
    上一篇http://www.2cto.com/kf/201412/365609.html</cn.c.mybutton></cn.c.mylinearlayout>
</cn.c.myframelayout>

结伴旅游,一个免费的交友网站:www.jieberu.com

推推族,免费得门票,游景区:www.tuituizu.com

Android事件分发详解(六)——ACTION_DOWN的消费验证的更多相关文章

  1. Android事件分发详解(三)——ViewGroup的dispatchTouchEvent()源码学习

    package cc.aa; import android.os.Environment; import android.view.MotionEvent; import android.view.V ...

  2. Android系统输入事件分发详解

    什么是输入事件? 我们知道,运行android系统的设备本质上是一台计算机,使用者在和计算机进行交互的时候可以抽象成简单的对计算机的输入和输出(IO).那么对于运行在计算机上的操作系统来说,操作系统在 ...

  3. Android事件分发机制详解(2)----分析ViewGruop的事件分发

    首先,我们需要 知道什么是ViewGroup,它和普通的View有什么区别? ViewGroup就是一组View的集合,它包含很多子View和ViewGroup,是Android 所有布局的父类或间接 ...

  4. 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象

    前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...

  5. 通俗理解Android事件分发与消费机制

    深入:Android Touch事件传递机制全面解析(从WMS到View树) 通俗理解Android事件分发与消费机制 说起Android滑动冲突,是个很常见的场景,比如SliddingMenu与Li ...

  6. Android 自定义 View 详解

    View 的绘制系列文章: Android View 绘制流程之 DecorView 与 ViewRootImpl Android View 的绘制流程之 Measure 过程详解 (一) Andro ...

  7. Android事件分发与责任链模式

    一.责任链模式 责任链模式是一种行为模式,为请求创建一个接收者的对象链.这样就避免,一个请求链接多个接收者的情况.进行外部解耦.类似于单向链表结构. 优点: 1. 降低耦合度.它将请求的发送者和接收者 ...

  8. Android事件分发机制二:viewGroup与view对事件的处理

    前言 很高兴遇见你~ 在上一篇文章 Android事件分发机制一:事件是如何到达activity的? 中,我们讨论了触摸信息从屏幕产生到发送给具体 的view处理的整体流程,这里先来简单回顾一下: 触 ...

  9. 本以为精通Android事件分发机制,没想到被面试官问懵了

    文章中出现的源码均基于8.0 前言 事件分发机制不仅仅是核心知识点更是难点,并且还是View的一大难题滑动冲突解决方法的理论基础,因此掌握好View的事件分发机制是十分重要的. 一.基本认识 1. 事 ...

随机推荐

  1. leveldb Arena

    背景我们都知道,对于一个高性能的服务器端程序来说,内存的使用非常重要.C++提供了new/delete来管理内存的申请和释放,但是对于小对象来说,直接使用new/delete代价比较大,要付出额外的空 ...

  2. webpack的介绍

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA5EAAAGpCAIAAACbBiUBAAAgAElEQVR4Aey9CVwb553/L04JcSPuw5

  3. POJ 3585 Accumulation Degree 题解

    题面 一句话题意:找一个点使得,使得从这个点出发作为源点,发出的流量最大,输出这个最大的流量 这道题是换根法+二次扫描的模板: 首先若确定1为原点,那么可以写出dp方程:当v的度是1时, g[u]+= ...

  4. 会引起全表扫描的几种SQL 以及sql优化 (转)

    出处: 查询语句的时候尽量避免全表扫描,使用全扫描,索引扫描!会引起全表扫描的几种SQL如下 1.模糊查询效率很低: 原因:like本身效率就比较低,应该尽量避免查询条件使用like:对于like ‘ ...

  5. php开发环境推荐使用

    万丈高楼平地起,好用得环境才能建立宏伟大厦,php开发环境推荐使用 1,自己安装 lamp 环境 linux+apache+mysql+php 2,自己安装 lnmp 环境 linux+nginx+m ...

  6. liunx 环境下安装 Eclipse C++

    第一步:首先安装JDK 进入JDK官网:https://www.oracle.com/technetwork/java/javase/downloads/index.html  下载对应的jdk 注意 ...

  7. sql server ABS函数和PI函数

    --ABS(x)返回x的绝对值 --PI()返回圆周率的值

  8. [转载]Linux运行模式及紧急、救援模式

    运行模式 在Linux中,存在一个叫init(initialize)的进程,其进程号是1,该进程存在一个对应的配置文件inittab,叫做系统的运行级别配置文件,位置在/etc/inittab.(但是 ...

  9. vue与angular 区别

    1.vue的双向数据绑定是基于 Es5中的getter和setter来实现的,而angular而是由自己实现的一套模板编译规则,需要进行 ‘脏’ 检查,vue则不需要,因此,vue性能上更高一些,但是 ...

  10. JS计算两个经纬度的距离

    var mapNumberUtil = {}; /** * 计算两个经纬度的距离(千米) */mapNumberUtil.getDistance = function(lat1, lng1, lat2 ...