传智播客旗下高端IT在线教育平台|咨询热线:010-56288220

返回顶部 返回列表
522 0

[猩球计划] View 的 onTouchEvent 方法

[复制链接]

24

主题

46

帖子

331

积分

中级会员

Bravian

Rank: 3Rank: 3

积分
331
5220 Bravian 发表于 2017-6-23 12:07:47
View 的 onTouchEvent 方法主要做了如下事情:
  • 如果 view 是 clickable 或者 longclickable,但是却处于 disable 状态,view 不做状态不做任何反应,直接消耗掉 touch 事件
  • 如果 view 是 clickable 或者 longclickable,处于 enable 状态,响应 view 的 touch 事件
    a. 修改 view 的 press 状态,focus 状态 等等状态
    b. 产生 click 和 longclick 事件


  1. public boolean onTouchEvent(MotionEvent event) {
  2.     final float x = event.getX();
  3.     final float y = event.getY();
  4.     final int viewFlags = mViewFlags;

  5.     // 处理 view 是 disable 的情况,如果 view 是 clickable 会消耗事件
  6.     if ((viewFlags & ENABLED_MASK) == DISABLED) {
  7.         if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
  8.             setPressed(false);
  9.         }
  10.         // A disabled view that is clickable still consumes the touch
  11.         // events, it just doesn't respond to them.
  12.         return (((viewFlags & CLICKABLE) == CLICKABLE ||
  13.                 (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
  14.     }

  15.     // 调用 TouchEvent 代理处理这个 TouchEvent
  16.     if (mTouchDelegate != null) {
  17.         if (mTouchDelegate.onTouchEvent(event)) {
  18.             return true;
  19.         }
  20.     }

  21.     if (((viewFlags & CLICKABLE) == CLICKABLE ||
  22.             (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
  23.         switch (event.getAction()) {
  24.             case MotionEvent.ACTION_UP:
  25.                 boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
  26.                 if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
  27.                     // take focus if we don't have it already and we should in
  28.                     // touch mode.
  29.                     boolean focusTaken = false;
  30.                     if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
  31.                         focusTaken = requestFocus();
  32.                     }

  33.                     if (prepressed) {
  34.                         // The button is being released before we actually
  35.                         // showed it as pressed.  Make it show the pressed
  36.                         // state now (before scheduling the click) to ensure
  37.                         // the user sees it.
  38.                         setPressed(true, x, y);
  39.                    }

  40.                     if (!mHasPerformedLongPress) {
  41.                         // This is a tap, so remove the longpress check
  42.                         removeLongPressCallback();

  43.                         // Only perform take click actions if we were in the pressed state
  44.                         if (!focusTaken) {
  45.                             // Use a Runnable and post this rather than calling
  46.                             // performClick directly. This lets other visual state
  47.                             // of the view update before click actions start.
  48.                             if (mPerformClick == null) {
  49.                                 mPerformClick = new PerformClick();
  50.                             }
  51.                             if (!post(mPerformClick)) {
  52.                                 performClick();
  53.                             }
  54.                         }
  55.                     }

  56.                     if (mUnsetPressedState == null) {
  57.                         mUnsetPressedState = new UnsetPressedState();
  58.                     }

  59.                     if (prepressed) {
  60.                         postDelayed(mUnsetPressedState,
  61.                                 ViewConfiguration.getPressedStateDuration());
  62.                     } else if (!post(mUnsetPressedState)) {
  63.                         // If the post failed, unpress right now
  64.                         mUnsetPressedState.run();
  65.                     }

  66.                     removeTapCallback();
  67.                 }
  68.                 break;

  69.             case MotionEvent.ACTION_DOWN:
  70.                 mHasPerformedLongPress = false;

  71.                 if (performButtonActionOnTouchDown(event)) {
  72.                     break;
  73.                 }

  74.                 // Walk up the hierarchy to determine if we're inside a scrolling container.
  75.                 boolean isInScrollingContainer = isInScrollingContainer();

  76.                 // For views inside a scrolling container, delay the pressed feedback for
  77.                 // a short period in case this is a scroll.
  78.                 if (isInScrollingContainer) {
  79.                     mPrivateFlags |= PFLAG_PREPRESSED;
  80.                     if (mPendingCheckForTap == null) {
  81.                         mPendingCheckForTap = new CheckForTap();
  82.                     }
  83.                     mPendingCheckForTap.x = event.getX();
  84.                     mPendingCheckForTap.y = event.getY();
  85.                     postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
  86.                 } else {
  87.                     // Not inside a scrolling container, so show the feedback right away
  88.                     setPressed(true, x, y);
  89.                     checkForLongClick(0);
  90.                 }
  91.                 break;

  92.             case MotionEvent.ACTION_CANCEL:
  93.                 setPressed(false);
  94.                 removeTapCallback();
  95.                 removeLongPressCallback();
  96.                 break;

  97.             case MotionEvent.ACTION_MOVE:
  98.                 drawableHotspotChanged(x, y);

  99.                 // Be lenient about moving outside of buttons
  100.                 if (!pointInView(x, y, mTouchSlop)) {
  101.                     // Outside button
  102.                     removeTapCallback();
  103.                     if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
  104.                         // Remove any future long press/tap checks
  105.                         removeLongPressCallback();

  106.                         setPressed(false);
  107.                     }
  108.                 }
  109.                 break;
  110.         }
  111.         // 只要可点击,View 就会自己来处理点击事件,消耗掉这一些列 Touch Event
  112.         return true;
  113.     }

  114.     return false;
  115. }
复制代码






回复

您需要登录后才可以回帖 登录 | 立即注册