android touchEvent解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件。 一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?我只能很肯定的对你说不一定。

android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件。
一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP
当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?我只能很肯定的对你说不一定。呵呵,为什么呢?看看下面我的调查结果你就明白了。
android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev)  这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent

当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由  dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。

通过语言描述这个处理逻辑很抽象,下面就用代码来具体说明一下。

layout配置文件 main.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <test.com.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:orientation="vertical"
 4     android:layout_width="fill_parent"
 5     android:layout_height="fill_parent"
 6     android:gravity="center" >
 7        <test.com.MyTextView 
 8             android:layout_width="200px"
 9             android:layout_height="200px"
10             android:id="@+id/tv"
11             android:text="lzqdiy"
12             android:textSize="40sp"
13             android:textStyle="bold"
14             android:background="#FFFFFF"
15             android:textColor="#0000FF"/>
16 </test.com.MyLinearLayout>

 

一个LinearLayout中添加了一个TextView。
下面是java代码:

public class TestTouchEventApp extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

java 代码 LinearLayout

View Code
public class TestTouchEventApp extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
package test.lzqdiy;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyLinearLayout extends LinearLayout {
    private final String TAG = "MyLinearLayout";

    public MyLinearLayout(Context context, AttributeSet attrs) {

        super(context, attrs);

        Log.d(TAG, TAG);

    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction();

        switch (action) {

        case MotionEvent.ACTION_DOWN:

            Log.d(TAG, "dispatchTouchEvent action:ACTION_DOWN");

            break;

        case MotionEvent.ACTION_MOVE:

            Log.d(TAG, "dispatchTouchEvent action:ACTION_MOVE");

            break;

        case MotionEvent.ACTION_UP:

            Log.d(TAG, "dispatchTouchEvent action:ACTION_UP");

            break;

        case MotionEvent.ACTION_CANCEL:

            Log.d(TAG, "dispatchTouchEvent action:ACTION_CANCEL");

            break;

        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        switch (action) {

        case MotionEvent.ACTION_DOWN:

            Log.d(TAG, "onInterceptTouchEvent action:ACTION_DOWN");

            break;

        case MotionEvent.ACTION_MOVE:

            Log.d(TAG, "onInterceptTouchEvent action:ACTION_MOVE");

            break;

        case MotionEvent.ACTION_UP:

            Log.d(TAG, "onInterceptTouchEvent action:ACTION_UP");

            break;

        case MotionEvent.ACTION_CANCEL:

            Log.d(TAG, "onInterceptTouchEvent action:ACTION_CANCEL");

            break;

        }

        return false;

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        switch (action) {

        case MotionEvent.ACTION_DOWN:

            Log.d(TAG, "---onTouchEvent action:ACTION_DOWN");

            break;

        case MotionEvent.ACTION_MOVE:

            Log.d(TAG, "---onTouchEvent action:ACTION_MOVE");

            break;

        case MotionEvent.ACTION_UP:

            Log.d(TAG, "---onTouchEvent action:ACTION_UP");

            break;

        case MotionEvent.ACTION_CANCEL:

            Log.d(TAG, "---onTouchEvent action:ACTION_CANCEL");

            break;

        }

        return true;
    }

}

 

java代码 TextView

View Code
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

public class MyTextView extends TextView {

    private final String TAG = "MyTextView";

    public MyTextView(Context context, AttributeSet attrs) {

        super(context, attrs);

    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction();

        switch (action) {

        case MotionEvent.ACTION_DOWN:

            Log.d(TAG, "dispatchTouchEvent action:ACTION_DOWN");

            break;

        case MotionEvent.ACTION_MOVE:

            Log.d(TAG, "dispatchTouchEvent action:ACTION_MOVE");

            break;

        case MotionEvent.ACTION_UP:

            Log.d(TAG, "dispatchTouchEvent action:ACTION_UP");

            break;

        case MotionEvent.ACTION_CANCEL:

            Log.d(TAG, "onTouchEvent action:ACTION_CANCEL");

            break;

        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        switch (action) {

        case MotionEvent.ACTION_DOWN:

            Log.d(TAG, "---onTouchEvent action:ACTION_DOWN");

            break;

        case MotionEvent.ACTION_MOVE:

            Log.d(TAG, "---onTouchEvent action:ACTION_MOVE");

            break;

        case MotionEvent.ACTION_UP:

            Log.d(TAG, "---onTouchEvent action:ACTION_UP");

            break;

        case MotionEvent.ACTION_CANCEL:

            Log.d(TAG, "---onTouchEvent action:ACTION_CANCEL");

            break;

        }

        return true;

    }

}

 

 

测试结果:

为了指代方便,下面将MyLinearLayout简称为L,将MyTextView简称为T,L.onInterceptTouchEvent=true 表示的含义为MyLinearLayout中的onInterceptTouchEvent方法返回值为true,通过程序运行时输出的Log来说明调用时序。
第1种情况 L.onInterceptTouchEvent=false&& L.onTouchEvent=true &&T.onTouchEvent=true 输出下面的Log:
D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_DOWN
D/MyTextView(11865): dispatchTouchEvent action:ACTION_DOWN
D/MyTextView(11865): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_MOVE
D/MyTextView(11865): dispatchTouchEvent action:ACTION_MOVE
D/MyTextView(11865): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_UP
D/MyTextView(11865): dispatchTouchEvent action:ACTION_UP
D/MyTextView(11865): ---onTouchEvent action:ACTION_UP
结论:TouchEvent完全由TextView处理。
第2种情况  L.onInterceptTouchEvent=false&& L.onTouchEvent=true &&T.onTouchEvent=false 输出下面的Log:
D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): onInterceptTouchEvent action:ACTION_DOWN
D/MyTextView(13101): dispatchTouchEvent action:ACTION_DOWN
D/MyTextView(13101): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_UP
结论:TextView只处理了ACTION_DOWN事件,LinearLayout处理了所有的TouchEvent。
第3种情况  L.onInterceptTouchEvent=true&& L.onTouchEvent=true 输出下面的Log:
D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): onInterceptTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_UP
结论:LinearLayout处理了所有的TouchEvent。
第4种情况  L.onInterceptTouchEvent=true&& L.onTouchEvent=false 输出下面的Log:
D/MyLinearLayout(13452): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13452): onInterceptTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13452): ---onTouchEvent action:ACTION_DOWN
结论:LinearLayout只处理了ACTION_DOWN事件,那么其他的TouchEvent被谁处理了呢?答案是LinearLayout最外层的Activity处理了TouchEvent。

 

 

 

 

目录
相关文章
|
16天前
|
安全 Android开发 iOS开发
安卓与iOS的较量:技术特性与用户体验的深度解析
在移动操作系统的战场上,安卓和iOS一直占据着主导地位。本文将深入探讨这两大平台的核心技术特性,以及它们如何影响用户的体验。我们将从系统架构、应用生态、安全性能和创新功能四个方面进行比较,帮助读者更好地理解这两个系统的异同。
45 3
|
1天前
|
缓存 Android开发 开发者
Android RecycleView 深度解析与面试题梳理
本文详细介绍了Android开发中高效且功能强大的`RecyclerView`,包括其架构概览、工作流程及滑动优化机制,并解析了常见的面试题。通过理解`RecyclerView`的核心组件及其优化技巧,帮助开发者提升应用性能并应对技术面试。
17 8
|
1天前
|
存储 缓存 Android开发
Android RecyclerView 缓存机制深度解析与面试题
本文首发于公众号“AntDream”,详细解析了 `RecyclerView` 的缓存机制,包括多级缓存的原理与流程,并提供了常见面试题及答案。通过本文,你将深入了解 `RecyclerView` 的高性能秘诀,提升列表和网格的开发技能。
16 8
|
2天前
|
搜索推荐 Linux Android开发
深入解析安卓与iOS系统架构设计差异
本文旨在探讨Android和iOS两大主流操作系统在架构设计上的根本差异。通过分析两种系统的设计理念、核心组件以及实际应用表现,揭示它们如何反映不同的开发哲学和用户体验策略。我们将从系统层级结构、内存管理机制、用户界面设计三个方面入手,逐一对比Android的开放性和灵活性如何与其对手iOS的封闭性和一致性相互辉映。
|
7天前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
19 0
|
1月前
|
搜索推荐 Java Android开发
安卓与iOS开发差异深度解析
【8月更文挑战第20天】在移动应用开发的广阔舞台上,安卓与iOS这两大操作系统各领风骚,它们在设计理念、开发环境、用户群体等方面展现出各自独特的风貌。本文将深入探讨这两个平台在开发过程中的主要差异,帮助开发者更好地理解并选择适合自己项目需求的平台。
|
1月前
|
JSON Java Android开发
Android 开发者必备秘籍:轻松攻克 JSON 格式数据解析难题,让你的应用更出色!
【8月更文挑战第18天】在Android开发中,解析JSON数据至关重要。JSON以其简洁和易读成为首选的数据交换格式。开发者可通过多种途径解析JSON,如使用内置的`JSONObject`和`JSONArray`类直接操作数据,或借助Google提供的Gson库将JSON自动映射为Java对象。无论哪种方法,正确解析JSON都是实现高效应用的关键,能帮助开发者处理网络请求返回的数据,并将其展示给用户,从而提升应用的功能性和用户体验。
42 1
|
20天前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
80 0
|
21天前
|
开发者 算法 虚拟化
惊爆!Uno Platform 调试与性能分析终极攻略,从工具运用到代码优化,带你攻克开发难题成就完美应用
【8月更文挑战第31天】在 Uno Platform 中,调试可通过 Visual Studio 设置断点和逐步执行代码实现,同时浏览器开发者工具有助于 Web 版本调试。性能分析则利用 Visual Studio 的性能分析器检查 CPU 和内存使用情况,还可通过记录时间戳进行简单分析。优化性能涉及代码逻辑优化、资源管理和用户界面简化,综合利用平台提供的工具和技术,确保应用高效稳定运行。
32 0
|
21天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
全面解析TensorFlow Lite:从模型转换到Android应用集成,教你如何在移动设备上轻松部署轻量级机器学习模型,实现高效本地推理
【8月更文挑战第31天】本文通过技术综述介绍了如何使用TensorFlow Lite将机器学习模型部署至移动设备。从创建、训练模型开始,详细演示了模型向TensorFlow Lite格式的转换过程,并指导如何在Android应用中集成该模型以实现预测功能,突显了TensorFlow Lite在资源受限环境中的优势及灵活性。
49 0

推荐镜像

更多