XXX事件



http://my.oschina.net/fuckboogie/blog/343131

http://blog.csdn.net/yanbober/article/details/45912661


http://www.th7.cn/Program/Android/201405/202993.shtml





深入理解android中的View.

http://www.incoding.org/admin/archives/179.html

http://www.2cto.com/kf/201407/313429.html

http://www.2cto.com/kf/201407/313429.html

http://www.2cto.com/kf/201211/171106.html

http://www.2cto.com/kf/201211/171106.html




http://www.2cto.com/kf/201211/171106.html


http://www.2cto.com/kf/201407/313429.html


http://blog.csdn.net/myarrow/article/details/14223493


http://blog.csdn.net/sunny2come/article/details/8899138



http://blog.csdn.net/yanbober/article/details/45932123


http://www.360doc.com/content/12/0823/21/7662927_231975556.shtml


http://blog.csdn.net/xipiaoyouzi/article/details/8098506


http://blog.csdn.net/chziroy/article/details/44401615



http://blog.csdn.net/mydreamongo/article/details/29812395


http://www.open-open.com/lib/view/open1434465083583.html


http://www.infoq.com/cn/articles/android-event-delivery-mechanism





magnet:?xt=urn:btih:f9e0079a2c1f2372529271b3667b0e8155143465





好,大家上一次我给大家分享了一下 android中的消息处理模型。

接下来我将继续把我对 android中的事件处理机制的理解  毫无保留的 分享给大家 。

希望大家能从我所分享的内容中学到一些东西。

好,我为什么想给大家分享 android中的事件处理模型,主要是这部分内容:

是我们自定义View过程中的核心知识点和难点。

深入理解了   android中的事件处理 模型 能够帮助我们 更好 的去 开发自定义控件,和去解决一些 莫名其妙的问题。



当然要想 开发  酷炫 的 自定义控件,只是理解 android中的事件处理 模型  是不够的。


因为自定义控件的开发  是一门 综合的知识点 ,它不仅需要我们理解 android中的事件处理 模型 

  它还需要我们掌握    android中的View 绘制 原理 和 各种数学函数 和 各种View动画 的使用 。 


关于 View 绘制 原理 和 各种动画的使用 ,  如果有时间的的 后边我会给大家一一的分享 

今天主要是带大家学习一下  android中的 事件处理模型。



好,

讲android的事件处理 模型之前我们先明白以下几个概念 。


什么是触摸事件?    由用户触摸(Touch)手机屏幕 所触发的软件事件。 




触摸事件发生的过程中会有好多的事件状态 :


ACTION_DOWN, //表示用户手指按下了屏幕。

ACTION_MOVE,//表示用户手指在屏幕上进行了移动。

ACTION_UP //表示用户手指离开了屏幕

ACTION_CANCEL //表示取消手势,不会由用户产生,而是由程序产生的






触摸事件你从何处来:     触摸事件如何进行分发?



一个触摸事件首先是在硬件层面触发,然后逐层传递到软件直至我们的app,前面的细节一般来说不用了解,我们讨论的事件入口从Activity开始。




当我们用手指触摸 屏幕的时候 ,


我们都知道 每一个界面都是一个activity, Activity的作用是用来展示相应的界面并且和用户进行交互。   Activity中所展示的内容 通常是各种各样的视图组件(View)或ViewGroup 。   我们大家都知道  ViewGroup和View   它们都是屏幕上的一个矩形区域并且负责界面绘制和处理事件,它们都是用来构建用户界面组件 的基类


它们的区别是 ? ViewGroup 继承自View,它可以是一组View的集合,它可以包涵 很多的子View和子VewGroup,

而View是界面展示区域的最小单位,它是不能包含子View的。




这些都是我们所知道的内容, 由此我们可以设想 android中的事件分发机制  是 由activity来开始分发的 ,  在上一节我给大家讲android消息 分发的机制的时候给大家讲过当一个消息从MessageQueue中被取出后,会调用Message的成员变量handler的 dispatchMessage方法来分发这个消息,而当我们用手指去触摸屏幕的时候,是否也会有一个类似怎样的 dispatch 方法 来 分发我们的 Touch事件呢 ?  这个时候我们是不是得到actiivty中看一下有没有怎样的一个方法呀。  好,我们看一下,这个图是截取的activity源码当中的 方法





/**

     * Called to process touch screen events.  You can override this to

     * intercept all touch screen events before they are dispatched to the

     * window.  Be sure to call this implementation for touch screen events

     * that should be handled normally.

     * 

     * @param ev The touch screen event.

     * 

     * @return boolean Return true if this event was consumed.

     */

    public boolean dispatchTouchEvent(MotionEvent ev) {

        if (ev.getAction() == MotionEvent.ACTION_DOWN) {

            onUserInteraction();

        }

        if (getWindow().superDispatchTouchEvent(ev)) {

            return true;

        }

        return onTouchEvent(ev);

    }


好,大家看一下这个方法的注释:

注释是说调用这个方法去处理触摸屏事件,在它分发到窗口之前,你可以去复写这个方法去拦截所有的触摸屏事件,

好,由此也给大家证明了android中的触摸事件的分发是以 activity中的 dispatchTouchEvent方法为入口函数的。


好,接下来我们就以这个方法去顺藤摸瓜就一下android中的触摸事件是怎样进行分发的。

大家可以看到,这个方法首先判断了 触摸事件是否为 按下事件,如果是的话,就会调用 onUserInteraction();方法。


紧接着调用了getWindow().superDispatchTouchEvent(ev)方法 ,如果这个方法返回true,就代表这个事件被

消费掉了, 好,那我们看一下getWindow方法中做了什么事件,好,这个方法返回了一个 Window mWindow

 对象 ,这个对象在什么时候被创建出来的呢?我们看一下 , 是在activity的attach 方法中被创建出来的 ,那attach方法是在什么时候

被调用的呢? 在上一讲中我给大家提到过, activity生命周期的调度是通过activityThread来完成的,好 那我们接下来来看一下

activityThread中的方法,好,大家这个类当中有一个 performLaunchActivity 方法,  

这个方法的作用 就是为应用程序进程中创建一个新的Activity实例 ,好那我们看一下这个方法当中 都做了什么事件,

 这个方法首先 通过 ActivityClientRecord来得到当前要启动的ActivityInfo,ActivityInfo的作用是用来描述当前正在启动的Activity组件的,

然后调用    r.intent.getComponent();  方法 ActivityInfo中得到我们要启动的组件信息Component, ,然后调用 r.packageInfo.getClassLoader();方法来

得到 我们的类加载器 , 紧接着 调用 了 mInstrumentation.newActivity(  cl, component.getClassName(), r.intent);方法 用反射的方式 来 创建我们的activity实例

,activity的实例创建出来之后 ,接着调用 了  activity.attach()方法 ,好,我们继承看一下 activity.attach()方法方法中都做了什么事情 。

这个方法中调用了 PolicyManager.makeNewWindow(this); 方法来为我们创建了一个 mWindow 的实例对象  。 由于  Window 中 一个接口,接着我们继续分析

一下它具体创建的是那一个实现类。 好,我们看一下 PolicyManager.makeNewWindow(this);方法内部  它调用了sPolicy.makeNewWindow(context);方法

sPolicy是什么,大家看一下这个类的静态方法块 , 在这个静态方法块是   它通过 调用 Class.forName 方法来得到我们要的这个类的字节码文件对象 ,

接着调用了 policyClass.newInstance(); 来实例这个 Policy 对象,然后又调用了 Policy身上的 makeNewWindow方法 ,好,我们继续看一下 Policy身上的


makeNewWindow方法都做了什么事情 ,好,大家可以看到这个方法直接 给我们返回了一个 PhoneWindow(context) 对象 。  


由此我们就知道 了 activity中的getWindow()方法就是返回给我们一个 PhoneWindow对象 .

好,那我们继续看一下   PhoneWindow 对象的  superDispatchTouchEvent 方法中都做了什么事情 。

好,大家可以看到这个方法中 又调用了  mDecor.superDispatchTouchEvent(event) 方法, 那mDecor 是什么它又是在什么时候创建出来的呢?

我们来搜一下 ,我们可以看到 mDecor 是在  installDecor()方法 中被赋值的 ,好,那我们在来看一下 generateDecor() 方法内部做了什么事件 。


好,大家这个方法内部直接 给我们返回了一个  DecorView 对象 。 由此我们也就知道  mDecor.superDispatchTouchEvent(event) 就是调用了


DecorView身上的 superDispatchTouchEvent 方法 , 好,那我们继续看一下 superDispatchTouchEvent 方法中都做了什么事情 。


那,它调用了 super.dispatchKeyEvent(event) ,super关键字代表父类的意思,它调用了父类的  dispatchKeyEvent 方法,


那它的父类是谁呢,我们看一下 ,DecorView extends FrameLayout  ,它的父类是  FrameLayout ,而 FrameLayout的父类又是 ViewGroup

所以它最终还是调用了  ViewGroup的  dispatchKeyEvent 。



 @Override

    public boolean superDispatchTouchEvent(MotionEvent event) {

        return mDecor.superDispatchTouchEvent(event);


    }



当Activity中所有的视图View都不处理该事件的是就交给Activity的onTouchEvent方方来处理。



DecorView的分发事件代码如下:


 @Override

        public boolean dispatchTouchEvent(MotionEvent ev) {

            final Callback cb = getCallback();

            return cb != null && mFeatureId < 0 ? cb.dispatchTouchEvent(ev) : super

                    .dispatchTouchEvent(ev);


        }






1)ViewGroup永远不会对拦截,因为他的onInterceptTouchEvent(MotionEvent ev)始终返回的是false!这样DecorView对到来的事件MotionEvent就只有分发到子View并由子View进行拦截和处理此事件了.



这里所说的事件是指手指按下(down)、移动(move)、抬起(up)此为一个事件集合或者说是事件序列




android控件对事件处理的优先级:onTouch>onTouchEvent>onClick


这个View是所有视图的根视图,Activity界面中你能见到的各个View都是DecorView的子View。到此为止事件已经分发到View上面,View获取到事件后有两个选择:处理和不处理该事件,如果处理该事件那事件就不会继续向其子View分发下去;否则就继续分发下去交给子View对该事件做同样的判断,其实就是个递归的过程。







1 ,onTouch和onTouchEvent有什么区别



我们讨论的事件入口从Activity开始。




触摸事件你到何处去:    触摸事件如何进行响应?





                           

触摸事件的传递顺序是:

Activity -> 当前活动窗口(PhoneWindow) -> 窗口的Top-Level View(DecorView) -> 各级ViewGroup (如各种Layout) -> ... -> 各级ViewGroup -> 叶子节点 View




而触摸事件的处理顺序则刚好相反:

叶子节点 View -> 各级ViewGroup -> ... -> 各级ViewGroup -> (Window和DecorView只有分发没有处理) -> Activity

当叶子节点View接受到事件之后,会试图做出处理,如果它处理了,则上面各层不再处理,如果它没有处理则往上由它的父ViewGroup处理,这样逐层向上按顺序试图处理,直到Activity。






  • Android中事件传递按照从上到下进行层级传递,事件处理从Activity开始到ViewGroup再到View。




在View和ViewGroup中都存在dispatchTouchEvent和onTouchEvent方法,但是在ViewGroup中还有一个onInterceptTouchEvent方法,



MotionEvent继承于InputEvent,用于标记各种动作事件。



  • dispatchTouchEvent方法用于事件的分发,Android中所有的事件都必须经过这个方法的分发,然后决定是自身消费当前事件还是继续往下分发给子控件处理。返回true表示不继续分发,事件没有被消费。返回false则继续往下分发,如果是ViewGroup则分发给onInterceptTouchEvent进行判断是否拦截该事件。
  • onTouchEvent方法用于事件的处理,返回true表示消费处理当前事件,返回false则不处理,交给子控件进行继续分发。
  • onInterceptTouchEvent是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截,返回true的时候表示拦截当前事件,不继续往下分发,交给自身的onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的(iOS可以)。


http://www.infoq.com/cn/articles/android-event-delivery-mechanism







在android开发设计模式中,最广泛应用的就是监听、回调,进而形成了事件响应的过程。





ViewGroup?它和普通的View有什么区别?

1 ,onTouch和onTouchEvent有什么区别


ViewGroup 继承自View,它可以就是一组View的集合,它包涵 很多的子View和子VewGroup,





注册一个监听对象

实现监听对象的监听事件

当某一触发事件到来,在触发事件中通过注册过的监听对象,回调注册对象的响应事件,来完成用户自定义实现。


dispatchTouchEvent:  函数负责事件的分发

onTouchEvent: 函数负责执行事件的处理,负责处理事件,主要处理MotionEvent.ACTION_DOWN、

MotionEvent.ACTION_MOVE 、

MotionEvent.ACTION_UP这三个事件。



http://blog.csdn.net/androiddevelop/article/details/18898971

http://blog.csdn.net/androiddevelop/article/details/18898971

http://blog.csdn.net/androiddevelop/article/details/18898971



http://my.oschina.net/banxi/blog/56421

http://my.oschina.net/banxi/blog/56421


重要:

http://www.incoding.org/admin/archives/179.html



1 ,dispatchTouchEvent主要用来分发事件,函数主要作用是来决定当前的事件是交由自己消费处理,还是交由子控件处理。

2 ,onInterceptTouchEvent主要来决定当前控件是否需要拦截传递给子控件,如果返回True表示该控件拦截,并交由自己父类的dispatchTouchEvent处理消费,如果返回false表示不拦截,允许传递给子控件处理。


3,dispatchTransformedTouchEvent主要根据传来的子控件,决定是自身处理消费,还是交由子控件处理消费。


4 ,ViewGroup中 onInterceptTouchEvent 默认是返回false的。


public boolean onInterceptTouchEvent(MotionEvent ev) {

        return false;


    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值