美文网首页
Android View系统之事件分发机制

Android View系统之事件分发机制

作者: mFrankHon | 来源:发表于2018-03-13 23:55 被阅读0次
类型 相关方法 Activity ViewGroup View
事件分发 dispatchTouuchEvent Y Y Y
事件拦截 onInterceptTouchEvent N Y N
事件消费 onTouchEvent Y Y Y

View的dispatchTouchEvent源码:

ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }

            if (!result && onTouchEvent(event)) {
                result = true;
            }

消费View事件的两种方式

  • onTouch
      View对象可以通过setOnClickListener来设置一个Event的监听者,这样当事件来临时,View会主动调用listener来告知对方。从优先级来看,这种方式较下面的onTouchEvent先行处理。
  • onTouchEvent
      假如用户没有指定OntouchListener,或者flags被指明为disabled,又或者onTouch的返回值为false(代表这一事件没有被处理),那么系统会将event传给onTouchEvent。

   可知,onTouch 优先于 onTouchEvent执行

MotionEvent有多种类型,常见有:

  • ACTION_DOWN
  • ACTION_MOVE
  • ACTION_UP

ViewGroup的dispatchTouchEvent源码:

boolean handled = false;
        if (onFilterTouchEventForSecurity(ev)) {
            final int action = ev.getAction();
            final int actionMasked = action & MotionEvent.ACTION_MASK;

            // Handle an initial down.
            if (actionMasked == MotionEvent.ACTION_DOWN) {
                // Throw away all previous state when starting a new touch gesture.
                // The framework may have dropped the up or cancel event for the previous gesture
                // due to an app switch, ANR, or some other state change.
                cancelAndClearTouchTargets(ev);
                resetTouchState();
            }

            // Check for interception.
            final boolean intercepted;
            if (actionMasked == MotionEvent.ACTION_DOWN
                    || mFirstTouchTarget != null) {
                final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
                if (!disallowIntercept) {
                    intercepted = onInterceptTouchEvent(ev);
                    ev.setAction(action); // restore action in case it was changed
                } else {
                    intercepted = false;
                }
            } else {
                // There are no touch targets and this action is not an initial down
                // so this view group continues to intercept touches.
                intercepted = true;
            }

            // If intercepted, start normal event dispatch. Also if there is already
            // a view that is handling the gesture, do normal event dispatch.
            if (intercepted || mFirstTouchTarget != null) {
                ev.setTargetAccessibilityFocus(false);
            }

            // Check for cancelation.
            final boolean canceled = resetCancelNextUpFlag(this)
                    || actionMasked == MotionEvent.ACTION_CANCEL;

            // Update list of touch targets for pointer down, if needed.
            final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
            TouchTarget newTouchTarget = null;
            boolean alreadyDispatchedToNewTouchTarget = false;
            if (!canceled && !intercepted) {
                    ...//when intercepted is false.
                }
  1. ViewGroup是继承自View
  2. 事件传递的顺序
    Activity -> PhoneWindow -> DecorView(由ActionBar和ContentView组成) -> ViewGroup -> ... -> View

相关文章

网友评论

      本文标题:Android View系统之事件分发机制

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