美文网首页Android技术知识Android开发Android开发经验谈
Android开发小知识5—事件分发机制详细解析

Android开发小知识5—事件分发机制详细解析

作者: Koume | 来源:发表于2017-12-12 13:09 被阅读88次

    事件概论

    在Android开发中,事件的处理是非常重要的一部分,Android程序的事件流程参考了Java中的事件处理操作。 如要进行事件处理,必须要有一个事件源。事件源的产生可以有很多形式,如单击按钮、长按等,之后根据此事件源找到相应的事件处理操作类对事件进行处理。这篇文章中将详细的分析Android事件。

    事件处理流程图.png

    上图中事件处理主要涉及3个对象:

    • Event Source(事件源):事件发生的场所,可以简单的理解为组件。
    • Event(事件):事件封装了界面组件上发生的特定事件,通常是用户的操作,比如点击事件。可以通过Event获取具体事件。
    • Event Listener(事件监听器):监听事件源所发生的事件,并做出相应的处理。

    事件监听器

    事件监听器是View类中包含一个回调方法的接口。 当用户与APP发生交互,触发已注册此视图的监听器时,Android 将调用这些方法。

    View.OnClickListener:当用户点击组件时, 调用此方法。

    View.OnLongClickListener: 当用户长按组件时,将调用此方法。此方法必须返回一个布尔值,返回 true 表示您已经处理事件且事件应就此停止;如果您尚未处理事件和或事件应该继续传递给其他任何点击监听器,则返回 false。

    View.OnFocusChangeListener: 当组件的焦点改变时,将调用此方法。

    View.OnKeyListener:当APP的键盘发生状态改变时,将调用此方法。此方法必须返回一个布尔值,表示您是否已处理完事件,以及是否应该将它继续传下去。 也就是说,返回 true 表示您已经处理事件且事件应就此停止;如果您尚未处理事件和或事件应该继续传递给其他任何按键监听器,则返回 false。

    View.OnTouchListener: 当用户执行可视为触摸事件的操作时,其中包括按下、释放或屏幕上的任何移动手势,将调用此方法。在复杂的布局中,此方法的调用永远一定的先后顺序(在后面将详细提及)。

    View.OnCreateContextMenuListener: 当需要生成菜单时,将调用此方法。

    这些方法是其相应接口的唯一成员。要定义其中一个方法并处理事件,一般的做法是在 Activity 中实现嵌套接口或将其定义为匿名类。然后,将实现的实例传递给相应的View.set...Listener()方法.例如,调用setOnClickListener()并向其传递OnClickListener实现。

    匿名类实现
    button.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      //TODO someting
                  }
              });
    

    事件处理程序(Event)

    默认事件处理程序的回调方法中,有如下几种用于事件处理的常见回调,其中包括:

    • onKeyDown(int, KeyEvent):在发生新的按键事件时调用。
    • onKeyUp(int, KeyEvent):在发生按键弹起事件时调用。
    • onTrackballEvent(MotionEvent):在发生轨迹球运动事件时调用。
    • onTouchEvent(MotionEvent):在发生触摸屏运动事件时调用。
    • onFocusChanged(boolean, int, Rect):在视图获得或失去焦点时调用。
    事件的类型:

    ACTION_DOWN:表示用户开始触摸。
    ACTION_MOVE:表示用户在移动(手指或者其他)。
    ACTION_UP:表示用户抬起了手指。
    ACTION_CANCEL:表示手势被取消了。
    ACTION_OUTSIDE:表示用户触碰超出了正常的UI边界。
    ACTION_POINTER_DOWN:有一个非主要的手指按下了。
    ACTION_POINTER_UP:一个非主要的手指抬起来了。

    事件发生的位置,x,y轴:

    getX():获得事件发生时,触摸的中间区域在屏幕的X轴。
    getY() :获得事件发生时,触摸的中间区域在屏幕的X轴。
    在多点触控中还可以通过:
    getX(int pointerIndex):来获得对应手指事件的发生位置. 获得X轴用。
    getY(int pointerIndex):来获得对应手指事件的发生位置. 获得Y轴用 。

    事件分发机制

    在管理布局内更复杂的事件时,对于事件的响应处理会从最顶层的组件不断向子组件传递,一直到最后的View组件。因此,在复杂布局中,对事件的处理也要考虑一下如下方法。

    onTouchEvent:在发生触摸屏运动事件时调用。是真正用来进行业务逻辑处理的地方,返回true表示已经将该事件消费,返回false表明事件继续传递。

    onInterceptTouchEvent:此方法允许ViewGroup监视分派给子视图的事件,返回false表示无需拦截,则递归的调用子组件的dispatchTouchEvent。返回true表示需要拦截,则直接调用本组件的onTouchEvent方法进行处理。因此,次方法只会存在于ViewGroup中。

    dispatchTouchEvent:此方法的情况比较复杂,要区分在ViewGroup和View中的其区别。
    ViewGroupdispatchTouchEvent()具体的执行逻辑:

    首先执行本组件的onInterceptTouchEvent。如果返回false,表明无需拦截,则调用第二个方法,即子组件的dispatchTouchEvent方法;如果返回true,无需向子组件传递,则直接调用本组件的onTouchEvent方法。 如果需要向子组件传递事件。如果递归调用子组件的dispatchTouchEvent返回false,则调用本组件的onTouchEvent方法;如果递归调用子组件的dispatchTouchEvent返回true,则无需调用本组件的onTouchEvent方法。 最后子组件的dispatchTouchEvent的返回值会返回给父组件的dispatchTouchEvent方法。

    view中的dispatchTouchEvent会直接调用其自身的onTouchEvent

    ViewGroup`dispatchTouchEvent()`.png

    总结

    对于事件,重要的是在设计开发中的应用和理解。这里只是分享了我的一些认识。如有不足之处,希望多多指出。文章参考了AndroidAPI指南Android MotionEvent事件响应机制

    原文作者litterMay
    原文链接:http://www.jianshu.com/p/8e8e048fa61e

    相关文章

      网友评论

        本文标题:Android开发小知识5—事件分发机制详细解析

        本文链接:https://www.haomeiwen.com/subject/jpkkixtx.html