zoukankan      html  css  js  c++  java
  • 事件之父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上了,这个方法返回了 false,那么这个事件会从这个 view往上传递,都是onTouchEvent来接收。
    如果事件传递到某一层的子view的onTouchEvent上了,这个方法返回true,那么这个事件将不会向上传递了,由这个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给出的说明:

  • 相关阅读:
    TCP与UDP的差别以及TCP三次握手、四次挥手
    MAC帧格式、IPV4数据报格式、TCP报文格式、UDP数据报格式
    维特比算法(Viterbi)-实例讲解(暴力破解+代码实现)
    对ajax的理解
    get与post两种方式的优缺点
    什么是Ajax和JSON,它们的优缺点
    浅谈一下如何避免用户多次点击造成的多次请求
    ajax是什么?
    同步和异步的区别?
    如何解决跨域问题
  • 原文地址:https://www.cnblogs.com/awkflf11/p/6611026.html
Copyright © 2011-2022 走看看