/**
  * Duplicate touch events to child views. We want to dispatch a down motion event and the move
  * events to child views, but calling dispatchTouchEvent() causes StackOverflowError. Therefore we
  * do it manually.
  *
  * @param ev motion event to be passed to children
  * @param pendingEvents pending events like ACTION_DOWN. This will be passed to the children
  *     before ev
  */
 private void duplicateTouchEventForChildren(MotionEvent ev, MotionEvent... pendingEvents) {
   if (ev == null) {
     return;
   }
   for (int i = getChildCount() - 1; 0 <= i; i--) {
     View childView = getChildAt(i);
     if (childView != null) {
       Rect childRect = new Rect();
       childView.getHitRect(childRect);
       MotionEvent event = MotionEvent.obtainNoHistory(ev);
       if (!childRect.contains((int) event.getX(), (int) event.getY())) {
         continue;
       }
       float offsetX = -childView.getLeft();
       float offsetY = -childView.getTop();
       boolean consumed = false;
       if (pendingEvents != null) {
         for (MotionEvent pe : pendingEvents) {
           if (pe != null) {
             MotionEvent peAdjusted = MotionEvent.obtainNoHistory(pe);
             peAdjusted.offsetLocation(offsetX, offsetY);
             consumed |= childView.dispatchTouchEvent(peAdjusted);
           }
         }
       }
       event.offsetLocation(offsetX, offsetY);
       consumed |= childView.dispatchTouchEvent(event);
       if (consumed) {
         break;
       }
     }
   }
 }
示例#2
0
  @StressTest
  @UiThreadTest
  public void testRandomTouch() {
    MemoryLogger memoryLogger = new MemoryLogger("testRandomTouch", 100);

    viewManager.setKeyboardLayout(KeyboardLayout.TWELVE_KEYS);

    final int actions = 500;

    final Random random = new Random();
    Rect rect = getViewRect();

    memoryLogger.logMemory("start");
    for (int i = 0; i < actions; i++) {
      final int x = rect.left + random.nextInt(rect.width());
      final int y = rect.top + random.nextInt(rect.height());

      inputView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, x, y, 0));
      inputView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, x, y, 0));

      // updateRequest sends asynchronous message to server. So we need to wait a moment
      // for server processing.
      sleep(200);

      memoryLogger.logMemoryInterval();
    }
    memoryLogger.logMemory("start");
  }
  @Override
  public boolean dispatchTouchEvent(MotionEvent event) {
    if (!onFilterTouchEventForSecurity(event)) return false;

    int action = event.getAction();

    double dx = event.getX() - mCenterX;
    double dy = mCenterY - event.getY();
    double radius = Math.sqrt(dx * dx + dy * dy);

    // Check if the event should be dispatched to the shutter button.
    if (radius <= mShutterButtonRadius) {
      if (mIndicatorControlWheel.getVisibility() == View.VISIBLE) {
        mIndicatorControlWheel.onTouchOutBound();
      }
      if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) {
        return mShutterButton.dispatchTouchEvent(event);
      }
      return false;
    }

    if (mShutterButton.isPressed()) {
      // Send cancel to the shutter button if it was pressed.
      event.setAction(MotionEvent.ACTION_CANCEL);
      mShutterButton.dispatchTouchEvent(event);
      return true;
    }

    return mIndicatorControlWheel.dispatchTouchEvent(event);
  }
  @Override
  public boolean dispatchTouchEvent(MotionEvent e) {
    float x = e.getX();
    float y = e.getY();
    if (mDispatchTouchEventToHeaderView) {
      boolean result = mHeaderView != null && mHeaderView.dispatchTouchEvent(e);
      if (e.getAction() == MotionEvent.ACTION_CANCEL || e.getAction() == MotionEvent.ACTION_UP) {
        mDispatchTouchEventToHeaderView = false;
      }
      return result;
    }

    if (mHeaderView != null
        && x >= 0
        && x <= mHeaderView.getMeasuredWidth()
        && y >= 0
        && y <= (mHeaderView.getMeasuredHeight() - mCurHeaderViewPushUpDistance)
        && e.getAction() == MotionEvent.ACTION_DOWN
        && mHeaderView.getVisibility() == View.VISIBLE
        && mHeaderView.dispatchTouchEvent(e)) {
      mDispatchTouchEventToHeaderView = true;
      return true;
    } else {
      return super.dispatchTouchEvent(e);
    }
  }
  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {

    final float x = ev.getX();
    final float y = ev.getY();
    final int action = ev.getAction();

    if (action == MotionEvent.ACTION_DOWN
        && mTouchTarget == null
        && mPinnedSection != null
        && isPinnedViewTouched(mPinnedSection.view, x, y)) { // create touch target

      // user touched pinned view
      mTouchTarget = mPinnedSection.view;
      mTouchPoint.x = x;
      mTouchPoint.y = y;

      // copy down event for eventually be used later
      mDownEvent = MotionEvent.obtain(ev);
    }

    if (mTouchTarget != null) {
      if (isPinnedViewTouched(mTouchTarget, x, y)) { // forward event to pinned view
        mTouchTarget.dispatchTouchEvent(ev);
      }

      if (action == MotionEvent.ACTION_UP) { // perform onClick on pinned view
        super.dispatchTouchEvent(ev);
        performPinnedItemClick();
        clearTouchTarget();

      } else if (action == MotionEvent.ACTION_CANCEL) { // cancel
        clearTouchTarget();

      } else if (action == MotionEvent.ACTION_MOVE) {
        if (Math.abs(y - mTouchPoint.y) > mTouchSlop) {

          // cancel sequence on touch target
          MotionEvent event = MotionEvent.obtain(ev);
          event.setAction(MotionEvent.ACTION_CANCEL);
          mTouchTarget.dispatchTouchEvent(event);
          event.recycle();

          // provide correct sequence to super class for further handling
          super.dispatchTouchEvent(mDownEvent);
          super.dispatchTouchEvent(ev);
          clearTouchTarget();
        }
      }

      return true;
    }

    // call super if this was not our pinned view
    return super.dispatchTouchEvent(ev);
  }
示例#6
0
 /**
  * Override method to dispatch touch event to the dragged view.
  *
  * @param ev captured.
  * @return true if the touch event is realized over the drag or second view.
  */
 @Override
 public boolean onTouchEvent(MotionEvent ev) {
   viewDragHelper.processTouchEvent(ev);
   if (isClosed()) {
     return false;
   }
   boolean isDragViewHit = isViewHit(dragView, (int) ev.getX(), (int) ev.getY());
   boolean isSecondViewHit = isViewHit(secondView, (int) ev.getX(), (int) ev.getY());
   if (isMaximized()) {
     dragView.dispatchTouchEvent(ev);
   } else {
     dragView.dispatchTouchEvent(cloneMotionEventWithAction(ev, MotionEvent.ACTION_CANCEL));
   }
   return isDragViewHit || isSecondViewHit;
 }
示例#7
0
 public boolean onTouchEvent(MotionEvent event) {
   boolean eventCatch = false;
   long time = event.getEventTime();
   eventCatch = evaluateTouch(event);
   if (!eventCatch) {
     Vector<ARSphericalView> arViewReverse = new Vector<ARSphericalView>(getArViews());
     Collections.sort(arViewReverse);
     Iterator<ARSphericalView> it = arViewReverse.iterator();
     View v;
     while (it.hasNext() && !eventCatch) {
       v = it.next();
       eventCatch = v.dispatchTouchEvent(event);
       if (!poiMove) poiMove = ((MagnitudePOI) v).isShifted();
     }
   }
   if (!eventCatch) {
     if (event.getAction() == MotionEvent.ACTION_DOWN) {
       timeOfStart = time;
       inClick = true;
     } else if (inClick
         && event.getAction() == MotionEvent.ACTION_UP
         && (time - timeOfStart) > 1000) {
       LaunchAction();
       inClick = false;
     }
   }
   return true;
 }
示例#8
0
 public boolean dispatchTouchEvent(MotionEvent paramMotionEvent)
 {
   float f1 = paramMotionEvent.getRawX();
   float f2 = paramMotionEvent.getRawY();
   if ((this.f == null) && (this.a != null) && (this.a.getVisibility() == 0) && (this.b != null))
   {
     this.b.getLocationOnScreen(this.g);
     if ((f1 >= this.g[0]) && (f1 < this.g[0] + this.b.getWidth()) && (f2 >= this.g[1]) && (f2 < this.g[1] + this.b.getHeight())) {
       this.f = this.a;
     }
   }
   if ((this.f == null) && (this.a != null) && (this.a.getVisibility() == 0))
   {
     if ((this.d == null) || (this.d.getVisibility() != 0)) {
       break label269;
     }
     this.d.getLocationOnScreen(this.g);
     if (f2 >= this.g[1]) {
       this.f = this.a;
     }
     if (f2 >= this.g[1]) {
       this.f = this.a;
     }
   }
   int i = paramMotionEvent.getAction();
   if (this.f != null)
   {
     localView = this.f;
     if (paramMotionEvent.getAction() == 3)
     {
       localView.dispatchTouchEvent(paramMotionEvent);
       if ((i == 3) || (i == 1)) {
         this.f = null;
       }
     }
   }
   label269:
   while (this.e == null) {
     for (;;)
     {
       View localView;
       return true;
       if ((this.c != null) && (this.c.getVisibility() == 0))
       {
         this.c.getLocationOnScreen(this.g);
         break;
       }
       this.g[0] = 2147483647;
       this.g[1] = 2147483647;
       break;
       MotionEvent localMotionEvent = MotionEvent.obtain(paramMotionEvent);
       localMotionEvent.offsetLocation(getScrollX() - localView.getLeft(), getScrollY() - localView.getTop());
       localView.dispatchTouchEvent(localMotionEvent);
       localMotionEvent.recycle();
     }
   }
   this.e.a(i);
   return true;
 }
示例#9
0
 @Test
 public void dispatchTouchEvent_sendsMotionEventToOnTouchEvent() throws Exception {
   TouchableView touchableView = new TouchableView(null);
   MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 12f, 34f, 0);
   touchableView.dispatchTouchEvent(event);
   assertThat(touchableView.event, sameInstance(event));
   view.dispatchTouchEvent(event);
   assertThat(shadowOf(view).getLastTouchEvent(), sameInstance(event));
 }
 public boolean onTouchEvent(MotionEvent motionevent) {
   if (isTouchInPinnedHeader(motionevent)) {
     motionevent.setLocation(
         motionevent.getX(),
         motionevent.getY() - (float) mPinnedHeaderOffset - (float) mNavBottom);
     return mPinnedHeaderView.dispatchTouchEvent(motionevent);
   } else {
     return super.onTouchEvent(motionevent);
   }
 }
  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    if (((!mEnabled || !mInterceptTouch) && mMode == MODE_READY) || mAlwaysOpened) {
      return super.dispatchTouchEvent(ev);
    }

    if (mMode != MODE_FINISHED) {
      onTouchEvent(ev);

      if (mMode != MODE_SLIDE) {
        super.dispatchTouchEvent(ev);
      } else {
        MotionEvent cancelEvent = MotionEvent.obtain(ev);
        cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
        super.dispatchTouchEvent(cancelEvent);
        cancelEvent.recycle();
      }

      return true;
    } else {
      final int action = ev.getAction();

      Rect rect = new Rect();
      View menu = getChildAt(0);
      menu.getHitRect(rect);

      if (!rect.contains((int) ev.getX(), (int) ev.getY())) {
        if (action == MotionEvent.ACTION_UP && mCloseOnRelease && !mDispatchWhenOpened) {
          close();
          mCloseOnRelease = false;
        } else {
          if (action == MotionEvent.ACTION_DOWN && !mDispatchWhenOpened) {
            mCloseOnRelease = true;
          }

          onTouchEvent(ev);
        }

        if (mDispatchWhenOpened) {
          super.dispatchTouchEvent(ev);
        }

        return true;
      } else {
        onTouchEvent(ev);

        ev.offsetLocation(-menu.getLeft(), -menu.getTop());
        menu.dispatchTouchEvent(ev);

        return true;
      }
    }
  }
示例#12
0
 @Test
 public void dispatchTouchEvent_listensToFalseFromListener() throws Exception {
   view.setOnTouchListener(
       new View.OnTouchListener() {
         @Override
         public boolean onTouch(View view, MotionEvent motionEvent) {
           return false;
         }
       });
   MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 12f, 34f, 0);
   view.dispatchTouchEvent(event);
   assertThat(shadowOf(view).getLastTouchEvent(), sameInstance(event));
 }
  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    int action = ev.getAction() & MotionEvent.ACTION_MASK;
    if (action == MotionEvent.ACTION_DOWN) {
      mDownY = ev.getY();
      mHeaderOwnsTouch = mHeader != null && mDownY <= mHeader.getHeight() + mHeaderOffset;
    }

    boolean handled;
    if (mHeaderOwnsTouch) {
      if (mHeader != null && Math.abs(mDownY - ev.getY()) <= mTouchSlop) {
        handled = mHeader.dispatchTouchEvent(ev);
      } else {
        if (mHeader != null) {
          MotionEvent cancelEvent = MotionEvent.obtain(ev);
          cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
          mHeader.dispatchTouchEvent(cancelEvent);
          cancelEvent.recycle();
        }

        MotionEvent downEvent =
            MotionEvent.obtain(
                ev.getDownTime(),
                ev.getEventTime(),
                ev.getAction(),
                ev.getX(),
                mDownY,
                ev.getMetaState());
        downEvent.setAction(MotionEvent.ACTION_DOWN);
        handled = mList.dispatchTouchEvent(downEvent);
        downEvent.recycle();
        mHeaderOwnsTouch = false;
      }
    } else {
      handled = mList.dispatchTouchEvent(ev);
    }

    return handled;
  }
 @Override
 public boolean onTouchEvent(MotionEvent ev) {
   boolean result = super.onTouchEvent(ev);
   mTempRect.set(0, 0, 0, 0);
   for (int i = 0; i < getChildCount(); i++) {
     View child = getChildAt(i);
     if (child.getVisibility() == View.VISIBLE) {
       offsetRectIntoDescendantCoords(child, mTempRect);
       ev.offsetLocation(mTempRect.left, mTempRect.top);
       result = child.dispatchTouchEvent(ev) || result;
       ev.offsetLocation(-mTempRect.left, -mTempRect.top);
     }
   }
   return result;
 }
示例#15
0
  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    boolean ret = false;
    // Make sure that the infoWindow is shown and we have all the needed references
    if (marker != null && marker.isInfoWindowShown() && map != null && infoWindow != null) {
      // Get a marker position on the screen
      Point point = map.getProjection().toScreenLocation(marker.getPosition());

      // Make a copy of the MotionEvent and adjust it's location
      // so it is relative to the infoWindow left top corner
      MotionEvent copyEv = MotionEvent.obtain(ev);
      copyEv.offsetLocation(
          -point.x + (infoWindow.getWidth() / 2),
          -point.y + infoWindow.getHeight() + bottomOffsetPixels);

      // Dispatch the adjusted MotionEvent to the infoWindow
      ret = infoWindow.dispatchTouchEvent(copyEv);
    }
    // If the infoWindow consumed the touch event, then just return true.
    // Otherwise pass this event to the super class and return it's result
    return ret || super.dispatchTouchEvent(ev);
  }
 private void injectMotionEvent(int viewIndex, MotionEvent event, int action) {
   View v = getChildAt(viewIndex);
   event.setAction(action);
   v.dispatchTouchEvent(event);
 }
  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    final int action = ev.getAction();
    boolean wasHeaderChildBeingPressed = mHeaderChildBeingPressed;
    if (mHeaderChildBeingPressed) {
      final View tempHeader = getHeaderAt(mMotionHeaderPosition);
      final View headerHolder =
          mMotionHeaderPosition == MATCHED_STICKIED_HEADER
              ? tempHeader
              : getChildAt(mMotionHeaderPosition);
      if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
        mHeaderChildBeingPressed = false;
      }
      if (tempHeader != null) {
        tempHeader.dispatchTouchEvent(transformEvent(ev, mMotionHeaderPosition));
        tempHeader.invalidate();
        tempHeader.postDelayed(
            new Runnable() {
              public void run() {
                invalidate(
                    0,
                    headerHolder.getTop(),
                    getWidth(),
                    headerHolder.getTop() + headerHolder.getHeight());
              }
            },
            ViewConfiguration.getPressedStateDuration());
        invalidate(
            0, headerHolder.getTop(), getWidth(), headerHolder.getTop() + headerHolder.getHeight());
      }
    }

    switch (action & MotionEvent.ACTION_MASK) {
      case MotionEvent.ACTION_DOWN:
        if (mPendingCheckForTap == null) {
          mPendingCheckForTap = new CheckForHeaderTap();
        }
        postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());

        final int y = (int) ev.getY();
        mMotionY = y;
        mMotionHeaderPosition = findMotionHeader(y);
        if (mMotionHeaderPosition == NO_MATCHED_HEADER || mScrollState == SCROLL_STATE_FLING) {
          // Don't consume the event and pass it to super because we
          // can't handle it yet.
          break;
        } else {
          View tempHeader = getHeaderAt(mMotionHeaderPosition);
          if (tempHeader != null) {
            if (tempHeader.dispatchTouchEvent(transformEvent(ev, mMotionHeaderPosition))) {
              mHeaderChildBeingPressed = true;
              tempHeader.setPressed(true);
            }
            tempHeader.invalidate();
            if (mMotionHeaderPosition != MATCHED_STICKIED_HEADER) {
              tempHeader = getChildAt(mMotionHeaderPosition);
            }
            invalidate(
                0, tempHeader.getTop(), getWidth(), tempHeader.getTop() + tempHeader.getHeight());
          }
        }
        mTouchMode = TOUCH_MODE_DOWN;
        return true;
      case MotionEvent.ACTION_MOVE:
        if (mMotionHeaderPosition != NO_MATCHED_HEADER
            && Math.abs(ev.getY() - mMotionY) > mTouchSlop) {
          // Detected scroll initiation so cancel touch completion on
          // header.
          mTouchMode = TOUCH_MODE_REST;
          // if (!mHeaderChildBeingPressed) {
          final View header = getHeaderAt(mMotionHeaderPosition);
          if (header != null) {
            header.setPressed(false);
            header.invalidate();
          }
          final Handler handler = getHandler();
          if (handler != null) {
            handler.removeCallbacks(mPendingCheckForLongPress);
          }
          mMotionHeaderPosition = NO_MATCHED_HEADER;
          // }
        }
        break;
      case MotionEvent.ACTION_UP:
        if (mTouchMode == TOUCH_MODE_FINISHED_LONG_PRESS) {
          mTouchMode = TOUCH_MODE_REST;
          return true;
        }
        if (mTouchMode == TOUCH_MODE_REST || mMotionHeaderPosition == NO_MATCHED_HEADER) {
          break;
        }

        final View header = getHeaderAt(mMotionHeaderPosition);
        if (!wasHeaderChildBeingPressed) {
          if (header != null) {
            if (mTouchMode != TOUCH_MODE_DOWN) {
              header.setPressed(false);
            }

            if (mPerformHeaderClick == null) {
              mPerformHeaderClick = new PerformHeaderClick();
            }

            final PerformHeaderClick performHeaderClick = mPerformHeaderClick;
            performHeaderClick.mClickMotionPosition = mMotionHeaderPosition;
            performHeaderClick.rememberWindowAttachCount();

            if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
              final Handler handler = getHandler();
              if (handler != null) {
                handler.removeCallbacks(
                    mTouchMode == TOUCH_MODE_DOWN
                        ? mPendingCheckForTap
                        : mPendingCheckForLongPress);
              }

              if (!mDataChanged) {
                /*
                 * Got here so must be a tap. The long press
                 * would have triggered on the callback handler.
                 */
                mTouchMode = TOUCH_MODE_TAP;
                header.setPressed(true);
                setPressed(true);
                if (mTouchModeReset != null) {
                  removeCallbacks(mTouchModeReset);
                }
                mTouchModeReset =
                    new Runnable() {
                      @Override
                      public void run() {
                        mMotionHeaderPosition = NO_MATCHED_HEADER;
                        mTouchModeReset = null;
                        mTouchMode = TOUCH_MODE_REST;
                        header.setPressed(false);
                        setPressed(false);
                        header.invalidate();
                        invalidate(0, header.getTop(), getWidth(), header.getHeight());
                        if (!mDataChanged) {
                          performHeaderClick.run();
                        }
                      }
                    };
                postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
              } else {
                mTouchMode = TOUCH_MODE_REST;
              }
            } else if (!mDataChanged) {
              performHeaderClick.run();
            }
          }
        }
        mTouchMode = TOUCH_MODE_REST;
        return true;
    }
    return super.onTouchEvent(ev);
  }
示例#18
0
 // Pass all touches along to the handle, allowing the user to drag the panel closed from its
 // interior
 @Override
 public boolean onTouchEvent(MotionEvent event) {
   return mHandleView.dispatchTouchEvent(event);
 }