List of usage examples for android.view MotionEvent setAction
public final void setAction(int action)
From source file:com.xinkaishi.apple.xinweidian.CustomView.PinnedHeaderExpandableListView.java
/** * item?/* w w w .j a va 2 s . c o m*/ * */ @Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null) return super.onTouchEvent(ev); int action = MotionEventCompat.getActionMasked(ev); action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: int oldPos = mTouchPosition; mDownX = ev.getX(); mDownY = ev.getY(); mTouchState = TOUCH_STATE_NONE; mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); if (mTouchPosition == oldPos && mTouchView != null && mTouchView.isOpen()) { mTouchState = TOUCH_STATE_X; mTouchView.onSwipe(ev); return true; } View view = getChildAt(mTouchPosition - getFirstVisiblePosition()); if (mTouchView != null && mTouchView.isOpen()) { mTouchView.smoothCloseMenu(); mTouchView = null; return super.onTouchEvent(ev); } if (view instanceof SwipeItemLayout) { mTouchView = (SwipeItemLayout) view; } if (mTouchView != null) { mTouchView.onSwipe(ev); } break; case MotionEvent.ACTION_MOVE: float dy = Math.abs((ev.getY() - mDownY)); float dx = Math.abs((ev.getX() - mDownX)); if (mTouchState == TOUCH_STATE_X) { if (mTouchView != null) { mTouchView.onSwipe(ev); } getSelector().setState(new int[] { 0 }); ev.setAction(MotionEvent.ACTION_CANCEL); super.onTouchEvent(ev); return true; } else if (mTouchState == TOUCH_STATE_NONE) { if (Math.abs(dy) > MAX_Y) { mTouchState = TOUCH_STATE_Y; } else if (dx > MAX_X) { mTouchState = TOUCH_STATE_X; // if (mOnSwipeListener != null) { // mOnSwipeListener.onSwipeStart(mTouchPosition); // } } } break; case MotionEvent.ACTION_UP: if (mTouchState == TOUCH_STATE_X) { if (mTouchView != null) { mTouchView.onSwipe(ev); if (!mTouchView.isOpen()) { mTouchPosition = -1; mTouchView = null; } } // if (mOnSwipeListener != null) { // mOnSwipeListener.onSwipeEnd(mTouchPosition); // } ev.setAction(MotionEvent.ACTION_CANCEL); super.onTouchEvent(ev); return true; } break; } return super.onTouchEvent(ev); }
From source file:im.ene.lab.design.widget.coverflow.FeatureCoverFlow.java
@Override public boolean dispatchTouchEvent(MotionEvent ev) { final int action = ev.getAction(); final float xf = ev.getX(); final float yf = ev.getY(); final RectF frame = mTouchRect; if (action == MotionEvent.ACTION_DOWN) { if (mMotionTarget != null) { // this is weird, we got a pen down, but we thought it was // already down! // We should probably send an ACTION_UP to the current // target. mMotionTarget = null;//from w w w . ja v a 2s. c o m } // If we're disallowing intercept or if we're allowing and we didn't // intercept if (!onInterceptTouchEvent(ev)) { // reset this event's action (just to protect ourselves) ev.setAction(MotionEvent.ACTION_DOWN); // We know we want to dispatch the event down, find a child // who can handle it, start with the front-most child. final int count = getChildCount(); final int[] childOrder = new int[count]; for (int i = 0; i < count; i++) { childOrder[i] = getChildDrawingOrder(count, i); } for (int i = count - 1; i >= 0; i--) { final View child = getChildAt(childOrder[i]); if (child.getVisibility() == VISIBLE || child.getAnimation() != null) { getScrolledTransformedChildRectangle(child, frame); if (frame.contains(xf, yf)) { // offset the event to the view's coordinate system final float xc = xf - frame.left; final float yc = yf - frame.top; ev.setLocation(xc, yc); if (child.dispatchTouchEvent(ev)) { // Event handled, we have a target now. mMotionTarget = child; mTargetTop = frame.top; mTargetLeft = frame.left; return true; } break; } } } } } boolean isUpOrCancel = (action == MotionEvent.ACTION_UP) || (action == MotionEvent.ACTION_CANCEL); // The event wasn't an ACTION_DOWN, dispatch it to our target if // we have one. final View target = mMotionTarget; if (target == null) { // We don't have a target, this means we're handling the // event as a regular view. ev.setLocation(xf, yf); return onTouchEvent(ev); } // if have a target, see if we're allowed to and want to intercept its // events if (onInterceptTouchEvent(ev)) { final float xc = xf - mTargetLeft; final float yc = yf - mTargetTop; ev.setAction(MotionEvent.ACTION_CANCEL); ev.setLocation(xc, yc); if (!target.dispatchTouchEvent(ev)) { // target didn't handle ACTION_CANCEL. not much we can do // but they should have. } // clear the target mMotionTarget = null; // Don't dispatch this event to our own view, because we already // saw it when intercepting; we just want to give the following // event to the normal onTouchEvent(). return true; } if (isUpOrCancel) { mMotionTarget = null; mTargetTop = -1; mTargetLeft = -1; } // finally offset the event to the target's coordinate system and // dispatch the event. final float xc = xf - mTargetLeft; final float yc = yf - mTargetTop; ev.setLocation(xc, yc); return target.dispatchTouchEvent(ev); }
From source file:ac.robinson.mediaphone.MediaPhoneActivity.java
@Override public boolean dispatchTouchEvent(MotionEvent e) { if (e.getEventTime() < mResumeTime) { if (MediaPhone.DEBUG) { Log.d(DebugUtilities.getLogTag(this), "Discarded touch event with start time earlier than onResume()"); }/*from w w w . j a va2 s .c o m*/ return true; } if (mGestureDetector != null) { if (mGestureDetector.onTouchEvent(e)) { e.setAction(MotionEvent.ACTION_CANCEL); // swipe detected - don't do the normal event } } try { return super.dispatchTouchEvent(e); } catch (NullPointerException ex) { if (MediaPhone.DEBUG) { Log.d(DebugUtilities.getLogTag(this), "Catching touch event Null Pointer Exception; ignoring touch"); } return true; // reported on Play Store - see: http://stackoverflow.com/a/13031529/1993220 } }
From source file:com.haibison.android.anhuu.FragmentFiles.java
/** * This should be called after the owner activity has been created * successfully.//from www . ja va 2 s . com */ private void initGestureDetector() { mListviewFilesGestureDetector = new GestureDetector(getActivity(), new GestureDetector.SimpleOnGestureListener() { private Object getData(float x, float y) { int i = getSubViewId(x, y); if (i >= 0) return mViewFiles.getItemAtPosition(mViewFiles.getFirstVisiblePosition() + i); return null; }// getSubView() private int getSubViewId(float x, float y) { Rect r = new Rect(); for (int i = 0; i < mViewFiles.getChildCount(); i++) { mViewFiles.getChildAt(i).getHitRect(r); if (r.contains((int) x, (int) y)) return i; } return -1; }// getSubViewId() /** * Gets {@link Cursor} from {@code e}. * * @param e * {@link MotionEvent}. * @return the cursor, or {@code null} if not available. */ private Cursor getData(MotionEvent e) { Object o = getData(e.getX(), e.getY()); return o instanceof Cursor ? (Cursor) o : null; }// getDataModel() @Override public void onLongPress(MotionEvent e) { /* * Do nothing. */ }// onLongPress() @Override public boolean onSingleTapConfirmed(MotionEvent e) { /* * Do nothing. */ return false; }// onSingleTapConfirmed() @Override public boolean onDoubleTap(MotionEvent e) { if (mDoubleTapToChooseFiles) { if (mIsMultiSelection) return false; Cursor cursor = getData(e); if (cursor == null) return false; if (BaseFileProviderUtils.isDirectory(cursor) && BaseFile.FILTER_FILES_ONLY == mFilterMode) return false; /* * If mFilterMode == FILTER_DIRECTORIES_ONLY, files * won't be shown. */ if (mIsSaveDialog) { if (BaseFileProviderUtils.isFile(cursor)) { mTextSaveas.setText(BaseFileProviderUtils.getFileName(cursor)); /* * Always set tag after setting text, or tag * will be reset to null. */ mTextSaveas.setTag(BaseFileProviderUtils.getUri(cursor)); checkSaveasFilenameAndFinish(); } else return false; } else finish(BaseFileProviderUtils.getUri(cursor)); } // double tap to choose files else { /* * Do nothing. */ return false; } // single tap to choose files return true; }// onDoubleTap() @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { /* * Sometimes e1 or e2 can be null. This came from users' * experiences. */ if (e1 == null || e2 == null) return false; final int max_y_distance = 19;// 10 is too short :-D final int min_x_distance = 80; final int min_x_velocity = 200; if (Math.abs(e1.getY() - e2.getY()) < max_y_distance && Math.abs(e1.getX() - e2.getX()) > min_x_distance && Math.abs(velocityX) > min_x_velocity) { int pos = getSubViewId(e1.getX(), e1.getY()); if (pos >= 0) { /* * Don't let this event to be recognized as a * single tap. */ MotionEvent cancelEvent = MotionEvent.obtain(e1); cancelEvent.setAction(MotionEvent.ACTION_CANCEL); mViewFiles.onTouchEvent(cancelEvent); deleteFile(mViewFiles.getFirstVisiblePosition() + pos); } } /* * Always return false to let the default handler draw * the item properly. */ return false; }// onFling() });// mListviewFilesGestureDetector }
From source file:com.github.crvv.wubinput.wubi.dictionary.suggestions.SuggestionStripView.java
@Override public boolean onTouchEvent(final MotionEvent me) { // In the sliding input mode. {@link MotionEvent} should be forwarded to // {@link MoreSuggestionsView}. final int index = me.getActionIndex(); final int x = mMoreSuggestionsView.translateX((int) me.getX(index)); final int y = mMoreSuggestionsView.translateY((int) me.getY(index)); me.setLocation(x, y);/*from www.j a v a2s . c o m*/ if (!mNeedsToTransformTouchEventToHoverEvent) { mMoreSuggestionsView.onTouchEvent(me); return true; } // In sliding suggestion mode with accessibility mode on, a touch event should be // transformed to a hover event. final int width = mMoreSuggestionsView.getWidth(); final int height = mMoreSuggestionsView.getHeight(); final boolean onMoreSuggestions = (x >= 0 && x < width && y >= 0 && y < height); if (!onMoreSuggestions && !mIsDispatchingHoverEventToMoreSuggestions) { // Just drop this touch event because dispatching hover event isn't started yet and // the touch event isn't on {@link MoreSuggestionsView}. return true; } final int hoverAction; if (onMoreSuggestions && !mIsDispatchingHoverEventToMoreSuggestions) { // Transform this touch event to a hover enter event and start dispatching a hover // event to {@link MoreSuggestionsView}. mIsDispatchingHoverEventToMoreSuggestions = true; hoverAction = MotionEvent.ACTION_HOVER_ENTER; } else if (me.getActionMasked() == MotionEvent.ACTION_UP) { // Transform this touch event to a hover exit event and stop dispatching a hover event // after this. mIsDispatchingHoverEventToMoreSuggestions = false; mNeedsToTransformTouchEventToHoverEvent = false; hoverAction = MotionEvent.ACTION_HOVER_EXIT; } else { // Transform this touch event to a hover move event. hoverAction = MotionEvent.ACTION_HOVER_MOVE; } me.setAction(hoverAction); mMoreSuggestionsView.onHoverEvent(me); return true; }
From source file:com.grottworkshop.gwsswipelayout.SwipeLayout.java
@Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabledInAdapterView() || !isEnabled()) return true; if (!isSwipeEnabled()) return super.onTouchEvent(event); int action = event.getActionMasked(); ViewParent parent = getParent();//from w w w. ja v a 2s.c o m gestureDetector.onTouchEvent(event); Status status = getOpenStatus(); ViewGroup touching = null; if (status == Status.Close) { touching = getSurfaceView(); } else if (status == Status.Open) { touching = getBottomView(); } switch (action) { case MotionEvent.ACTION_DOWN: mDragHelper.processTouchEvent(event); parent.requestDisallowInterceptTouchEvent(true); sX = event.getRawX(); sY = event.getRawY(); if (touching != null) touching.setPressed(true); return true; case MotionEvent.ACTION_MOVE: { if (sX == -1 || sY == -1) { // Trick: // When in nested mode, we need to send a constructed ACTION_DOWN MotionEvent to mDragHelper, to help // it initialize itself. event.setAction(MotionEvent.ACTION_DOWN); mDragHelper.processTouchEvent(event); parent.requestDisallowInterceptTouchEvent(true); sX = event.getRawX(); sY = event.getRawY(); return true; } float distanceX = event.getRawX() - sX; float distanceY = event.getRawY() - sY; float angle = Math.abs(distanceY / distanceX); angle = (float) Math.toDegrees(Math.atan(angle)); boolean doNothing = false; if (mDragEdge == DragEdge.Right) { boolean suitable = (status == Status.Open && distanceX > 0) || (status == Status.Close && distanceX < 0); suitable = suitable || (status == Status.Middle); if (angle > 30 || !suitable) { doNothing = true; } } if (mDragEdge == DragEdge.Left) { boolean suitable = (status == Status.Open && distanceX < 0) || (status == Status.Close && distanceX > 0); suitable = suitable || status == Status.Middle; if (angle > 30 || !suitable) { doNothing = true; } } if (mDragEdge == DragEdge.Top) { boolean suitable = (status == Status.Open && distanceY < 0) || (status == Status.Close && distanceY > 0); suitable = suitable || status == Status.Middle; if (angle < 60 || !suitable) { doNothing = true; } } if (mDragEdge == DragEdge.Bottom) { boolean suitable = (status == Status.Open && distanceY > 0) || (status == Status.Close && distanceY < 0); suitable = suitable || status == Status.Middle; if (angle < 60 || !suitable) { doNothing = true; } } if (doNothing) { parent.requestDisallowInterceptTouchEvent(false); return false; } else { if (touching != null) { touching.setPressed(false); } parent.requestDisallowInterceptTouchEvent(true); mDragHelper.processTouchEvent(event); } break; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { sX = -1; sY = -1; if (touching != null) { touching.setPressed(false); } } default: parent.requestDisallowInterceptTouchEvent(true); mDragHelper.processTouchEvent(event); } return true; }
From source file:com.android.inputmethod.latin.suggestions.SuggestionStripView.java
@Override public boolean onTouchEvent(final MotionEvent me) { if (!mMoreSuggestionsView.isShowingInParent()) { // Ignore any touch event while more suggestions panel hasn't been shown. // Detecting sliding up is done at {@link #onInterceptTouchEvent}. return true; }/*from ww w . j a v a 2s. c o m*/ // In the sliding input mode. {@link MotionEvent} should be forwarded to // {@link MoreSuggestionsView}. final int index = me.getActionIndex(); final int x = mMoreSuggestionsView.translateX((int) me.getX(index)); final int y = mMoreSuggestionsView.translateY((int) me.getY(index)); me.setLocation(x, y); if (!mNeedsToTransformTouchEventToHoverEvent) { mMoreSuggestionsView.onTouchEvent(me); return true; } // In sliding suggestion mode with accessibility mode on, a touch event should be // transformed to a hover event. final int width = mMoreSuggestionsView.getWidth(); final int height = mMoreSuggestionsView.getHeight(); final boolean onMoreSuggestions = (x >= 0 && x < width && y >= 0 && y < height); if (!onMoreSuggestions && !mIsDispatchingHoverEventToMoreSuggestions) { // Just drop this touch event because dispatching hover event isn't started yet and // the touch event isn't on {@link MoreSuggestionsView}. return true; } final int hoverAction; if (onMoreSuggestions && !mIsDispatchingHoverEventToMoreSuggestions) { // Transform this touch event to a hover enter event and start dispatching a hover // event to {@link MoreSuggestionsView}. mIsDispatchingHoverEventToMoreSuggestions = true; hoverAction = MotionEvent.ACTION_HOVER_ENTER; } else if (me.getActionMasked() == MotionEvent.ACTION_UP) { // Transform this touch event to a hover exit event and stop dispatching a hover event // after this. mIsDispatchingHoverEventToMoreSuggestions = false; mNeedsToTransformTouchEventToHoverEvent = false; hoverAction = MotionEvent.ACTION_HOVER_EXIT; } else { // Transform this touch event to a hover move event. hoverAction = MotionEvent.ACTION_HOVER_MOVE; } me.setAction(hoverAction); mMoreSuggestionsView.onHoverEvent(me); return true; }
From source file:study.com.s_sxl.carelib.pullRefreshView.layout.FlingLayout.java
/******************************************************************/ @Override/* w w w . jav a 2s .co m*/ public boolean dispatchTouchEvent(MotionEvent ev) { if (mPullView != null && !ViewCompat.isNestedScrollingEnabled(mPullView)) { float moveY = getMoveY(); int pointerCount = ev.getPointerCount(); int pointerIndex = ev.getActionIndex(); if (!mScroller.isFinished()) { mScroller.abortAnimation(); } switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: mPointerId = ev.getPointerId(pointerIndex); float x = ev.getX(pointerIndex); float y = ev.getY(pointerIndex); tempY = downY = y; tempX = downX = x; tempStateType = SCROLL_STATE_TOUCH_SCROLL; if (moveY != 0) { return true; } break; case MotionEvent.ACTION_POINTER_DOWN: mPointerId = ev.getPointerId(pointerIndex); tempX = ev.getX(pointerIndex); tempY = ev.getY(pointerIndex); break; case MotionEvent.ACTION_MOVE: pointerIndex = ev.findPointerIndex(mPointerId); float mx; float my; if (pointerCount > pointerIndex && pointerIndex >= 0) { mx = ev.getX(pointerIndex); my = ev.getY(pointerIndex); } else { mx = ev.getX(); my = ev.getY(); } //????? int dataX = (int) (mx - tempX); int dataY = (int) (my - tempY); tempX = mx; tempY = my; if (isScrolling || (Math.abs(dataY) > Math.abs(dataX))) { isScrolling = true; if (moveY == 0) { // 0,0 //?? if ((dataY < 0 && canPullUp()) || (dataY > 0 && canPullDown())) { moveBy(dataY); return true; } } else { //?0,0 ev.setAction(MotionEvent.ACTION_CANCEL);//? if ((moveY < 0 && moveY + dataY >= 0) || (moveY > 0 && moveY + dataY <= 0)) { //0,0 ev.setAction(MotionEvent.ACTION_DOWN); moveTo(0); } else if ((moveY > 0 && dataY > 0) || (moveY < 0 && dataY < 0)) { //?? if (maxDistance == 0 || Math.abs(moveY) < maxDistance) { int ps = 0; int hDataY = dataY / 2; if (maxDistance == 0) { ps = (int) (-hDataY * Math.abs(moveY) / (float) MAXDISTANCE) - hDataY; } else { ps = (int) (-hDataY * Math.abs(moveY) / (float) maxDistance) - hDataY; } moveBy(ps + dataY); } else if (moveY > maxDistance) { moveTo(maxDistance); } else if (moveY < -maxDistance) { moveTo(-maxDistance); } } else { moveBy(dataY); } } } else { ev.setLocation(mx, downY); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: startFling(); isScrolling = false; break; case MotionEvent.ACTION_POINTER_UP: // ?? int pointerIdLeave = ev.getPointerId(pointerIndex); if (mPointerId == pointerIdLeave) { // ??????VelocityTracker int reIndex = pointerIndex == 0 ? 1 : 0; mPointerId = ev.getPointerId(reIndex); // ? tempY = ev.getY(reIndex); } } return super.dispatchTouchEvent(ev) || isScrolling; } else { return super.dispatchTouchEvent(ev); } }
From source file:com.ybao.pullrefreshview.layout.FlingLayout.java
/******************************************************************/ @Override//from ww w . j av a2 s.c om public boolean dispatchTouchEvent(MotionEvent ev) { if (mPullView != null && !ViewCompat.isNestedScrollingEnabled(mPullView)) { float moveY = getMoveY(); int pointerCount = ev.getPointerCount(); int pointerIndex = ev.getActionIndex(); if (!mScroller.isFinished()) { mScroller.abortAnimation(); } switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: mPointerId = ev.getPointerId(pointerIndex); float x = ev.getX(pointerIndex); float y = ev.getY(pointerIndex); tepmY = downY = y; tepmX = downX = x; tempStateType = SCROLL_STATE_TOUCH_SCROLL; if (moveY != 0) { return true; } break; case MotionEvent.ACTION_POINTER_DOWN: mPointerId = ev.getPointerId(pointerIndex); tepmX = ev.getX(pointerIndex); tepmY = ev.getY(pointerIndex); break; case MotionEvent.ACTION_MOVE: pointerIndex = ev.findPointerIndex(mPointerId); float mx; float my; if (pointerCount > pointerIndex && pointerIndex >= 0) { mx = ev.getX(pointerIndex); my = ev.getY(pointerIndex); } else { mx = ev.getX(); my = ev.getY(); } //????? int dataX = (int) (mx - tepmX); int dataY = (int) (my - tepmY); tepmX = mx; tepmY = my; if (isScrolling || (Math.abs(dataY) > Math.abs(dataX))) { isScrolling = true; if (moveY == 0) { // 0,0 //?? if ((dataY < 0 && canPullUp()) || (dataY > 0 && canPullDown())) { moveBy(dataY); return true; } } else { //?0,0 ev.setAction(MotionEvent.ACTION_CANCEL);//? if ((moveY < 0 && moveY + dataY >= 0) || (moveY > 0 && moveY + dataY <= 0)) { //0,0 ev.setAction(MotionEvent.ACTION_DOWN); moveTo(0); } else if ((moveY > 0 && dataY > 0) || (moveY < 0 && dataY < 0)) { //?? if (maxDistance == 0 || Math.abs(moveY) < maxDistance) { int ps = 0; int hDataY = dataY / 2; if (maxDistance == 0) { ps = (int) (-hDataY * Math.abs(moveY) / (float) MAXDISTANCE) - hDataY; } else { ps = (int) (-hDataY * Math.abs(moveY) / (float) maxDistance) - hDataY; } moveBy(ps + dataY); } else if (moveY > maxDistance) { moveTo(maxDistance); } else if (moveY < -maxDistance) { moveTo(-maxDistance); } } else { moveBy(dataY); } } } else { ev.setLocation(mx, downY); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: startFling(); isScrolling = false; break; case MotionEvent.ACTION_POINTER_UP: // ?? int pointerIdLeave = ev.getPointerId(pointerIndex); if (mPointerId == pointerIdLeave) { // ??????VelocityTracker int reIndex = pointerIndex == 0 ? 1 : 0; mPointerId = ev.getPointerId(reIndex); // ? tepmY = ev.getY(reIndex); } } return super.dispatchTouchEvent(ev) || isScrolling; } else { return super.dispatchTouchEvent(ev); } }
From source file:com.leap.mini.widget.pullrefresh.base.layout.FlingLayout.java
/******************************************************************/ @Override// ww w.j a v a2 s . co m public boolean dispatchTouchEvent(MotionEvent ev) { if (mPullView != null && !ViewCompat.isNestedScrollingEnabled(mPullView)) { float moveY = getMoveY(); int pointerCount = ev.getPointerCount(); int pointerIndex = ev.getActionIndex(); if (!mScroller.isFinished()) { mScroller.abortAnimation(); } switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: mPointerId = ev.getPointerId(pointerIndex); float x = ev.getX(pointerIndex); float y = ev.getY(pointerIndex); tepmY = downY = y; tepmX = downX = x; tempStateType = SCROLL_STATE_TOUCH_SCROLL; if (moveY != 0) { return true; } break; case MotionEvent.ACTION_POINTER_DOWN: mPointerId = ev.getPointerId(pointerIndex); tepmX = ev.getX(pointerIndex); tepmY = ev.getY(pointerIndex); break; case MotionEvent.ACTION_MOVE: pointerIndex = ev.findPointerIndex(mPointerId); float mx; float my; if (pointerCount > pointerIndex && pointerIndex >= 0) { mx = ev.getX(pointerIndex); my = ev.getY(pointerIndex); } else { mx = ev.getX(); my = ev.getY(); } // ????? int dataX = (int) (mx - tepmX); int dataY = (int) (my - tepmY); tepmX = mx; tepmY = my; if (isScrolling || (Math.abs(dataY) > Math.abs(dataX))) { isScrolling = true; if (moveY == 0) { // 0,0 // ?? if ((dataY < 0 && canPullUp()) || (dataY > 0 && canPullDown())) { moveBy(dataY); return true; } } else { // ?0,0 ev.setAction(MotionEvent.ACTION_CANCEL);// ? if ((moveY < 0 && moveY + dataY >= 0) || (moveY > 0 && moveY + dataY <= 0)) { // 0,0 ev.setAction(MotionEvent.ACTION_DOWN); moveTo(0); } else if ((moveY > 0 && dataY > 0) || (moveY < 0 && dataY < 0)) { // ?? if (maxDistance == 0 || Math.abs(moveY) < maxDistance) { int ps = 0; int hDataY = dataY / 2; if (maxDistance == 0) { ps = (int) (-hDataY * Math.abs(moveY) / (float) MAXDISTANCE) - hDataY; } else { ps = (int) (-hDataY * Math.abs(moveY) / (float) maxDistance) - hDataY; } moveBy(ps + dataY); } else if (moveY > maxDistance) { moveTo(maxDistance); } else if (moveY < -maxDistance) { moveTo(-maxDistance); } } else { moveBy(dataY); } } } else { ev.setLocation(mx, downY); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: startFling(); isScrolling = false; break; case MotionEvent.ACTION_POINTER_UP: // ?? int pointerIdLeave = ev.getPointerId(pointerIndex); if (mPointerId == pointerIdLeave) { // ??????VelocityTracker int reIndex = pointerIndex == 0 ? 1 : 0; mPointerId = ev.getPointerId(reIndex); // ? tepmY = ev.getY(reIndex); } } return super.dispatchTouchEvent(ev) || isScrolling; } else { return super.dispatchTouchEvent(ev); } }