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

Android中父View和子view的点击事件的执行过程

阅读更多

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上了,这个方法返回了 true,那么这个事件会从这个 view往上传递,都是onTouchEvent来接收。
如果事件传递到某一层的子view的onTouchEvent上了,这个方法返回false,那么这个事件将不会向上传递了,由这个view拦截处理.
而如果传递到最上面的 onTouchEvent也返回 false的话,这个事件就会“消失”,而且接收不到下一次事件

 

onInterceptTouchEvent()用于处理事件并改变事件的传递方向。处理事件这个不用说了,你在函数内部编写代码处理就可以了。而决定传递方向的是返回值,返回为false时事件会传递给子控件的onInterceptTouchEvent();返回值为true时事件会传递给当前控件的onTouchEvent(),而不在传递给子控件,这就是所谓的Intercept(截断)。

onTouchEvent() 用于处理事件,返回值决定当前控件是否消费(consume)了这个事件。可能你要问是否消费了又区别吗,反正我已经针对事件编写了处理代码?答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。

本文源地址:http://www.cnblogs.com/rocky_yi/archive/2011/01/21/1941522.html# ,转载请注明出处!

复制代码
<?xml version="1.0" encoding="utf-8"?>
<com.touchstudy.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation
="vertical"
    android:layout_width
="fill_parent"
    android:layout_height
="fill_parent" >
    
<com.touchstudy.LayoutView2
        
android:orientation="vertical"
        android:layout_width
="fill_parent"
        android:layout_height
="fill_parent"
        android:gravity
="center">
       
<com.touchstudy.MyTextView 
            
android:layout_width="wrap_content"
            android:layout_height
="wrap_content"
            android:id
="@+id/tv"
            android:text
="AB"
            android:textSize
="40sp"
            android:textStyle
="bold"
            android:background
="#FFFFFF"
            android:textColor
="#0000FF"/>
   
</com.touchstudy.LayoutView2>
</com.touchstudy.LayoutView1>
复制代码

 

 

在没有重写onInterceptTouchEvent()和onTouchEvent()的情况下(他们的返回值都是false), 对上面这个布局,MotionEvent事件的传递顺序如下:

 

当某个控件的onInterceptTouchEvent()返回值为true时,就会发生截断,事件被传到当前控件的onTouchEvent()。如我们将LayoutView2的onInterceptTouchEvent()返回值为true,则传递流程变成:

 

 如果我们同时将LayoutView2的onInterceptTouchEvent()和onTouchEvent()设置成true,那么LayoutView2将消费被传递的事件,同时后续事件(如跟着ACTION_DOWN的ACTION_MOVE或者ACTION_UP)会直接传给LayoutView2的onTouchEvent(),不传给其他任何控件的任何函数。同时传递给子空间一个ACTION_CANCEL事件。传递流程变成(图中没有画出ACTION_CANCEL事件):

          

附SDK给出的说明:

·  You will receive the down event here.
·  The down event will be handled either by a child of this view group, or given to your own onTouchEvent() method to handle; this means you should implement onTouchEvent() to return true, so you will continue to see the rest of the gesture (instead of looking for a parent view to handle it). Also, by returning true from onTouchEvent(), you will not receive any following events in onInterceptTouchEvent() and all touch processing must happen in onTouchEvent() like normal.
·  For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target's onTouchEvent().
·  If you return true from here, you will not receive any following events: the target view will receive the same event but with the action ACTION_CANCEL, and all further events will be delivered to your onTouchEvent() method and no longer appear here.
 
分享到:
评论

相关推荐

    Android中父View和子view的点击事件

    当父View和子View同时需要处理点击事件时,可能会出现冲突。例如,子View覆盖了父View的一部分,那么这部分区域的点击事件会被子View接收,父View无法获取。解决这种冲突有以下几种方式: 1. 子View设置`android:...

    Android判断touch事件点是否在view范围内的方法

    在Android应用开发中,处理触摸事件...总之,Android提供了丰富的API来处理触摸事件和View的几何属性,使得开发者能够创建出具有高度互动性的用户界面。通过熟练掌握这些技巧,可以让你的Android应用更加生动有趣。

    Android中自定义View

    在Android开发中,自定义View是一项重要的技能,它允许开发者根据需求创建独特的用户界面元素,以实现更加丰富和个性化的交互体验。自定义View通常涉及到绘制、事件处理、动画以及性能优化等多个方面。下面我们将...

    Android 通过NavigationView+DrawerLayout来实现侧滑菜单的功能和点击事件+弹出对话框

    在Android中,我们通常使用`NavigationView`和`DrawerLayout`这两个组件来实现这种功能。`NavigationView`用于创建菜单项,而`DrawerLayout`则作为容器,管理抽屉的滑入滑出行为。接下来,我们将详细探讨如何使用这...

    Android中View绘制流程

    在这个阶段,View会根据其测量尺寸和父View的布局规则确定每个子View的位置。对于ViewGroup来说,它需要遍历所有子View并调用它们的`layout()`方法来设定位置。 3. **onDraw()**:最后是绘制阶段,这是实际在屏幕上...

    Android自定义View的事件分发机制(一)

    在自定义View时,有时我们需要改变默认的事件分发行为,例如,可能需要让父View捕获原本属于子View的事件,这时就需要重写 `onInterceptTouchEvent()`。同时,`onTouchEvent()` 也需要进行适当的处理,以确保事件的...

    Android 全局悬浮View实现,以及悬浮view点击事件

    下面将详细介绍如何实现Android全局悬浮View,并讨论其点击事件的处理。 首先,我们需要创建悬浮按钮的布局。在布局文件中,我们可以使用`android.support.design.widget.FloatingActionButton`组件来创建悬浮按钮...

    Android 线程+View的使用

    在Android开发中,线程和View的交互是十分常见的需求,因为Android的UI操作必须在主线程中进行,而耗时的操作(如网络请求、大数据处理等)则应该放在子线程中。本实例主要探讨如何在子线程中更新View,通过两种方式...

    android获取根View的方法

    在Android开发中,根View(Root View)是布局文件中最高层次的视图容器,它包含并管理着应用界面中的所有子视图。根View通常是LinearLayout、RelativeLayout、FrameLayout等布局组件,它决定了子视图的排列方式和...

    Android AnimationProvider 点击View会带动画变大

    `AnimationProvider`是一个不太常见的概念,它可能指的是自定义的`ValueAnimator.AnimatorUpdateListener`或`Animation.AnimationListener`,用于在动画执行过程中提供更新或者监听动画状态。在这个场景下,我们讨论...

    android 动画被父布局遮盖问题解决1

    然而,有时候在实现动画过程中,我们可能会遇到这样一个问题:当一个View执行动画并移出其父布局时,它会被父布局自动裁剪,导致动画效果不完整。这个问题在标题“android 动画被父布局遮盖问题解决1”中被提及,并...

    Android特效开发(可伸缩View带互相挤压效果)下

    2. **onMeasure()**:在这个方法中,我们需要遍历所有子View,根据它们的权重或者固定尺寸来计算每个子View的测量宽度和高度。同时,考虑到伸缩效果,可以为每个子View设置一个最小和最大尺寸。 3. **onLayout()**...

    android循环view的实现

    3. 触摸事件处理:确保触摸事件的传递正确,防止与父View或其他子View的事件冲突。 通过以上步骤,我们可以实现一个自定义的循环View。当然,实际开发中可能还需要根据具体需求进行调整,如添加点击事件、增加翻页...

    android中动态更改View背景

    换肤功能通常涉及多个View的背景更改,可以使用遍历View树的方法,如递归遍历`ViewGroup`的子View,对每个View执行上述的背景更换操作。同时,为了提高效率,可以考虑使用缓存机制,预先加载和缓存可能使用的皮肤...

    android 自定义view比较综合的例子

    在Android开发中,自定义View是一项重要的技能,它允许开发者根据特定需求创建独特且功能丰富的用户界面。这个“android 自定义view比较综合的例子”显然涵盖了多个高级话题,旨在帮助有一定基础的开发者提升自定义...

    Android之Input子系统事件分发流程 - CSDN博客1

    在Android系统中,Input子系统是负责处理用户输入事件(如触摸屏点击、键盘按键等)的关键组件。本文将深入探讨Android Input子系统的事件分发流程,帮助开发者理解这一复杂而重要的过程。 首先,让我们从...

    android 子Viewy依次滑出界面转场

    "android 子View依次滑出界面转场"是一种常见的动画效果,通常用于活动(Activity)的退出或者进入,给用户带来流畅且吸引人的过渡体验。这种效果可以通过自定义动画和Android的动画框架来实现。 首先,Android提供...

    Android音频剪辑裁剪自定义view

    在Android开发中,实现音频剪辑和裁剪功能通常涉及到多媒体处理、自定义视图以及用户交互设计。本文将深入探讨如何创建一个Android音频剪辑裁剪的自定义View,以便用户可以通过拖动来调整音频的剪切时长,并通过滑块...

    android view OnTouchEvent 中同时处理 onClick,onLongClick,和左右移动事件

    在Android开发中,`View`的触摸事件处理是至关重要的,特别是当我们需要同时处理点击、长按以及滑动事件时。`OnTouchEvent`是`View`接收触摸输入的主要方法,而`onClick`、`onLongClick`和左右移动事件则是在用户与...

    Android 创建自定义View源码

    在Android开发中,创建自定义View是提升应用用户体验和实现独特设计的重要手段。自定义View允许开发者根据需求扩展系统默认的视图组件,或者构建完全原创的交互元素。本教程将深入探讨Android自定义View的源码实现...

Global site tag (gtag.js) - Google Analytics