`
xfjt297857539
  • 浏览: 152241 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

android 事件处理(转)

 
阅读更多
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
<?xml version="1.0" encoding="utf-8"?>
<test.lzqdiy.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:gravity="center" >
        <test.lzqdiy.MyTextView
            android:layout_width="200px"
             android:layout_height="200px"
             android:id="@+id/tv"
             android:text="lzqdiy"
             android:textSize="40sp"
             android:textStyle="bold"
             android:background="#FFFFFF"
             android:textColor="#0000FF"/>
</test.lzqdiy.MyLinearLayout>
节点层次很简单,一个LinearLayout中添加了一个TextView。
下面是java代码:
package test.lzqdiy;

import android.app.Activity;
import android.os.Bundle;

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;
     }

}

package test.lzqdiy;

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。
分享到:
评论

相关推荐

    Android事件处理机制详解及源码

    Android事件处理机制是Android应用程序开发中的关键组成部分,它使得用户与应用之间能够进行有效的交互。在Android系统中,事件处理主要包括触摸事件、键盘事件、广播事件等,这些事件的处理方式直接影响到应用的...

    android中处理各种触摸事件

    // 按下事件处理 } // 其他方法... } ``` #### 六、自定义处理逻辑 除了使用`GestureDetector`提供的默认手势处理方法之外,还可以自定义更复杂的逻辑来满足特定需求。例如,在上面的部分内容中,开发者在`...

    android事件分析

    首先,Android事件处理主要依赖于事件传递链(Event Dispatching Chain)。当用户在屏幕上进行操作时,比如点击或滑动,这些动作会被转换为事件对象,如MotionEvent或KeyEvent。事件首先由WindowManager服务捕获,...

    Android studio 实现图片翻转

    7. **触摸事件处理**:为了响应用户的翻转操作,需要在Activity或Fragment中监听触摸事件,通常通过重写`onTouchEvent()`方法,解析滑动或点击动作,然后启动相应的动画。 8. **动画过渡**:为了让翻转过程更加平滑...

    利用monkey注入事件原理实现Android 事件注入

    总结起来,利用monkey原理实现Android事件注入是一项涉及反射、蓝牙通信以及Android事件处理机制的复杂任务。它可以帮助开发者进行远程测试,提高应用的健壮性。同时,也应注意安全风险,避免滥用可能导致恶意操控的...

    Android图片放大缩小旋转完美demo

    在Android开发中,图片处理是一项常见且重要的任务。本文将基于标题"Android图片放大缩小旋转完美demo"和描述,深入探讨Android中如何实现图片的触摸缩放、旋转以及在网络环境下的加载,同时会提及到使用ViewPager...

    android4.0按键处理

    InputReader维护了一个线程安全的机制,以确保事件处理的并发性。 3. **InputDispatcher**: 当事件被InputMapper处理完后,InputDispatcher接手,它负责将事件分发给正确的窗口。InputDispatcher会考虑当前的输入...

    android 仿音量旋转按钮

    综上所述,“android 仿音量旋转按钮”的实现涉及到Android自定义View的开发,包括视图的绘制、事件处理、音量控制、动画以及布局集成等多个方面。通过这样的自定义控件,开发者可以为应用程序增添独特性和互动性,...

    Qt for android触摸手势事件QGestureEvent

    这些手势可以映射到特定的QGesture对象,由QGestureEvent类来封装并传递给相应的事件处理函数。 **QGestureEvent** QGestureEvent是Qt事件系统的一部分,它包含了在触摸屏上发生的所有手势信息。当用户执行手势时,...

    Android展示圆形转盘的代码例子

    文件 "ExmTurntable" 很可能包含了实现上述功能的源代码,包括自定义View类、动画配置、数据结构和事件处理逻辑。分析这个文件,可以深入理解Android自定义视图开发和动画实现的具体细节。对于初学者来说,这是一个...

    Android仿转转首页banner图

    在Android应用开发中,"Android仿转转首页banner图"是一个常见的需求,它涉及到UI设计、图片滚动效果、数据加载等多个技术点。转转作为知名的二手交易平台,其首页的banner图设计独特,具有吸引用户注意力的功能,...

    Android ontouch事件处理的三种方式

    在Android开发中,触摸事件是用户与应用交互的关键部分,`onTouchEvent`是处理这些事件的主要方法。本篇文章将深入探讨Android中处理`ontouch`事件的三种常见方式:通过接口实现、使用内部类以及利用匿名内部类。...

    android事件总线eclipse版demo

    在给定的“android事件总线eclipse版demo”中,我们将探讨如何在Eclipse环境下使用事件总线技术,特别是AndroidEventBus库。AndroidEventBus是由GreenRobot团队开发的一个轻量级的事件总线框架,它使得Android组件间...

    Android Button事件的实现

    在Android应用开发中,`Button`控件是最常用的交互组件之一,用户可以通过点击按钮触发相应的事件处理逻辑。本文将通过一个简单的例子来详细介绍如何在Android应用程序中实现`Button`事件。 #### 二、XML布局文件...

    最新Android旋转圆盘

    总的来说,"最新Android旋转圆盘"是一个结合了触摸事件处理、动画实现、布局管理和自定义属性的复杂自定义控件。通过理解并掌握其背后的实现原理和技术细节,开发者不仅可以提升自己的Android技能,也能为自己的应用...

    android-opengl图片3d旋转

    在实际开发中,你还需要处理触摸事件,让用户能够通过滑动或捏合手势控制3D旋转。这通常涉及对`MotionEvent`的处理,并将这些输入转换为旋转参数。 最后,确保正确处理纹理坐标和顶点坐标,以便在旋转过程中图片...

    Android 3D相册图片滑动+倾斜+放大+倒影处理源码.zip

    图片的滑动效果通常与触摸事件(TouchEvent)处理有关。Android提供了MotionEvent类用于处理用户的触摸输入,通过监听ACTION_DOWN、ACTION_MOVE和ACTION_UP等动作,我们可以获取到用户的滑动轨迹,进而控制图片的移动...

    Android-3D自动旋转的旋转木马

    在项目`AutoRotaryDemo-master`中,你将找到实现这些功能的代码,包括自定义的`GLSurfaceView`子类、3D模型加载与渲染、动画控制和事件处理。通过阅读和学习这些代码,你可以理解整个3D旋转木马的实现流程,并将其...

    android 系统应用程序 网络数据转串口tcpToUart

    综上所述,"android 系统应用程序 网络数据转串口tcpToUart"项目涵盖了Android应用开发、网络通信、串口操作、多线程编程等多个方面,需要开发者具备扎实的技术基础和实践经验。项目中的"tcp2uart"和"eloop"可能是...

Global site tag (gtag.js) - Google Analytics