List of usage examples for android.view MotionEvent obtain
static public MotionEvent obtain(MotionEvent other)
From source file:com.freshdigitable.udonroad.ffab.IndicatableFFAB.java
public IndicatableFFAB(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); final View v = View.inflate(context, R.layout.view_indicatable_ffab, this); indicator = (ActionIndicatorView) v.findViewById(R.id.iffab_indicator); ffab = (FlingableFAB) v.findViewById(R.id.iffab_ffab); ViewCompat.setElevation(indicator, ffab.getCompatElevation()); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IndicatableFFAB, defStyleAttr, R.style.Widget_FFAB_IndicatableFFAB); try {/*from w ww. j a va 2 s .c om*/ final Drawable fabIcon = a.getDrawable(R.styleable.IndicatableFFAB_fabIcon); ffab.setImageDrawable(fabIcon); final int fabTint = a.getColor(R.styleable.IndicatableFFAB_fabTint, NO_ID); if (fabTint != NO_ID) { ViewCompat.setBackgroundTintList(ffab, ColorStateList.valueOf(fabTint)); } final int indicatorTint = a.getColor(R.styleable.IndicatableFFAB_indicatorTint, 0); indicator.setBackgroundColor(indicatorTint); indicatorMargin = a.getDimensionPixelSize(R.styleable.IndicatableFFAB_marginFabToIndicator, 0); } finally { a.recycle(); } ffab.setOnTouchListener(new OnTouchListener() { private MotionEvent old; @Override public boolean onTouch(View view, MotionEvent motionEvent) { final int action = motionEvent.getAction(); if (action == MotionEvent.ACTION_DOWN) { old = MotionEvent.obtain(motionEvent); onStart(); return false; } final Direction direction = Direction.getDirection(old, motionEvent); if (action == MotionEvent.ACTION_MOVE) { onMoving(direction); } else if (action == MotionEvent.ACTION_UP) { old.recycle(); onFling(view.getHandler()); } return false; } private Direction prevSelected = Direction.UNDEFINED; public void onStart() { indicator.onActionLeave(prevSelected); prevSelected = Direction.UNDEFINED; indicator.setVisibility(View.VISIBLE); } public void onMoving(Direction direction) { if (prevSelected == direction) { return; } indicator.onActionLeave(prevSelected); if (isDirectionEnabled(direction)) { indicator.onActionSelected(direction); } prevSelected = direction; } private boolean isDirectionEnabled(Direction direction) { for (Direction d : enableDirections) { if (d == direction) { return true; } } return false; } public void onFling(Handler handler) { handler.postDelayed(new Runnable() { @Override public void run() { indicator.setVisibility(View.INVISIBLE); } }, 200); } }); if (isInEditMode()) { indicator.setVisibility(VISIBLE); } }
From source file:com.llf.nestlayout.library.NestedWebView.java
@Override public boolean onTouchEvent(MotionEvent event) { if (!isNestedScrollingEnabled()) return super.onTouchEvent(event); boolean rs = false; final int action = MotionEventCompat.getActionMasked(event); if (action == MotionEvent.ACTION_DOWN) { mNestedOffsetY = 0;//from w w w. j ava 2 s . c om super.onTouchEvent(event); } MotionEvent ne = MotionEvent.obtain(event); switch (action) { case MotionEvent.ACTION_DOWN: rs = super.onTouchEvent(ne); startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL); mTouchCancel = false; mLastX = (int) event.getX(); mLastY = (int) event.getY(); mTouchY = mLastY; break; case MotionEvent.ACTION_MOVE: final int y = (int) event.getY(); if (Math.abs(mTouchY - y) >= mTouchSlop) { //cancel click,Long click if (!mTouchCancel) { mTouchCancel = true; event.setAction(MotionEvent.ACTION_CANCEL); super.onTouchEvent(event); } int x = (int) event.getX(); int dx = mLastX - x; int dy = mLastY - y; int oldY = getScrollY(); if (dispatchNestedPreScroll(0, dy, mScrollConsumed, mScrollOffset)) { dy -= mScrollConsumed[1]; mNestedOffsetY += mScrollOffset[1]; } // overScrollBy(dx, dy, getScrollX(), oldY, computeHorizontalScrollRange(), computeVerticalScrollRange(), computeHorizontalScrollExtent(), computeVerticalScrollExtent(), true); mLastX = x; mLastY = y - mScrollOffset[1]; int scrollDelta = getScrollY() - oldY; dy -= scrollDelta; if (dispatchNestedScroll(0, scrollDelta, 0, dy, mScrollOffset)) { mNestedOffsetY += mScrollOffset[1]; mLastY -= mScrollOffset[1]; } rs = true; } else { rs = super.onTouchEvent(event); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (!mTouchCancel) rs = super.onTouchEvent(ne); stopNestedScroll(); break; } return rs; }
From source file:com.douban.rexxar.view.NestedWebView.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (!mEnableNestedScroll) { return super.onTouchEvent(ev); }//from w w w . j a v a 2 s . c om boolean returnValue = false; MotionEvent event = MotionEvent.obtain(ev); final int action = MotionEventCompat.getActionMasked(event); if (action == MotionEvent.ACTION_DOWN) { mNestedOffsetY = 0; } int eventX = (int) event.getX(); int eventY = (int) event.getY(); event.offsetLocation(0, -mNestedOffsetY); switch (action) { case MotionEvent.ACTION_MOVE: if (mNestedScrollEstablish) { mVelocityTracker.addMovement(ev); int deltaX = mLastX - eventX; int deltaY = mLastY - eventY; // ??? if (mOptimizeHorizontalScroll) { // ?? if (!mScrollHorizontalEstablish && !mScrollVerticalEstablish) { if (Math.abs(deltaX) > Math.abs(deltaY) * 1.5 && Math.abs(deltaX) > mTouchSlop) { mScrollHorizontalEstablish = true; } else if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > mTouchSlop) { mScrollVerticalEstablish = true; mFrozenX = eventX; } } } mLastX = eventX; if (mScrollHorizontalEstablish) { event.offsetLocation(0, deltaY); // ? returnValue = super.onTouchEvent(event); } else { // ? if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mOffsetInWindow)) { deltaY -= mScrollConsumed[1]; mLastY = eventY - mOffsetInWindow[1]; mNestedOffsetY += mOffsetInWindow[1]; event.offsetLocation(0, -mOffsetInWindow[1]); } else { mLastY = eventY; } // parent?consumedelta?webView? int oldScrollY = getScrollY(); if ((deltaY < 0 && getScrollY() > 0) || deltaY > 0) { // ??? if (mScrollVerticalEstablish) { event.offsetLocation(mFrozenX - eventX, 0); returnValue = super.onTouchEvent(event); } else { returnValue = super.onTouchEvent(event); } mLastYWebViewConsume = event.getY(); } else { // FIXME ?? if (mScrollVerticalEstablish) { event.offsetLocation(mFrozenX - eventX, mLastYWebViewConsume - event.getY()); } else { event.offsetLocation(0, mLastYWebViewConsume - event.getY()); } super.onTouchEvent(event); } // deltaY if (deltaY == getScrollY() - oldScrollY) { // ??? } else if (deltaY < getScrollY() - oldScrollY) { // if (getScrollY() <= 5) { int dyConsumed = oldScrollY - getScrollY(); int dyUnconsumed = deltaY - (getScrollY() - oldScrollY); if (dispatchNestedScroll(0, dyConsumed, 0, dyUnconsumed, mOffsetInWindow)) { mNestedOffsetY += mOffsetInWindow[1]; mLastY -= mOffsetInWindow[1]; event.offsetLocation(0, mOffsetInWindow[1]); } } returnValue = true; } else { // ??? } } } else { returnValue = super.onTouchEvent(event); } break; case MotionEvent.ACTION_DOWN: mLastYWebViewConsume = event.getY(); returnValue = super.onTouchEvent(event); mLastX = eventX; mLastY = eventY; // start NestedScroll mNestedScrollEstablish = startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL); mScrollHorizontalEstablish = false; mScrollVerticalEstablish = false; initOrResetVelocityTracker(); mVelocityTracker.addMovement(ev); break; case MotionEvent.ACTION_CANCEL: if (mNestedScrollEstablish) { returnValue = super.onTouchEvent(event); // end NestedScroll stopNestedScroll(); } else { returnValue = super.onTouchEvent(event); } mScrollHorizontalEstablish = false; mScrollVerticalEstablish = false; mFrozenX = 0; recycleVelocityTracker(); break; case MotionEvent.ACTION_UP: if (mNestedScrollEstablish) { if (mScrollHorizontalEstablish) { // ? event.offsetLocation(0, mLastY - eventY); } returnValue = super.onTouchEvent(event); final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) velocityTracker.getYVelocity(); if ((Math.abs(initialVelocity) > mMinimumVelocity) && getScrollY() == 0) { flingWithNestedDispatch(-initialVelocity); } else {// end NestedScroll stopNestedScroll(); } } else { returnValue = super.onTouchEvent(event); } mScrollHorizontalEstablish = false; mScrollVerticalEstablish = false; mFrozenX = 0; recycleVelocityTracker(); break; } return returnValue; }
From source file:com.thelastcrusade.soundstream.components.PlaylistFragment.java
@Override public void onResume() { super.onResume(); getActivity().setTitle(getTitle());/*from w ww . ja v a 2 s. co m*/ final GestureDetectorCompat songGesture = new GestureDetectorCompat(getActivity(), new PlaylistSongGestureListener(getListView())); getListView().setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (songGesture.onTouchEvent(event)) { if (event.getAction() != MotionEvent.ACTION_DOWN) { MotionEvent cancelEvent = MotionEvent.obtain(event); cancelEvent.setAction(MotionEvent.ACTION_CANCEL); v.onTouchEvent(cancelEvent); } return true; } return false; } }); }
From source file:org.floens.chan.controller.ui.NavigationControllerContainerLayout.java
@Override public boolean onInterceptTouchEvent(MotionEvent event) { if (!swipeEnabled || tracking || navigationController.isBlockingInput() || !navigationController.getTop().navigationItem.swipeable || getBelowTop() == null) { return false; }/*from w w w. j a v a 2 s. c o m*/ int actionMasked = event.getActionMasked(); if (actionMasked != MotionEvent.ACTION_DOWN && interceptedEvent == null) { // Action down wasn't called here, ignore return false; } switch (actionMasked) { case MotionEvent.ACTION_DOWN: // Logger.test("onInterceptTouchEvent down"); interceptedEvent = MotionEvent.obtain(event); break; case MotionEvent.ACTION_MOVE: { // Logger.test("onInterceptTouchEvent move"); float x = (event.getX() - interceptedEvent.getX()); float y = (event.getY() - interceptedEvent.getY()); if (Math.abs(y) >= slopPixels || interceptedEvent.getX() < dp(20)) { // Logger.test("blockTracking = true"); blockTracking = true; } if (!blockTracking && x >= minimalMovedPixels && Math.abs(x) > Math.abs(y)) { startTracking(event); return true; } break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: { // Logger.test("onInterceptTouchEvent cancel/up"); interceptedEvent.recycle(); interceptedEvent = null; blockTracking = false; break; } } return false; }
From source file:org.wikipedia.page.bottomcontent.BottomContentHandler.java
public BottomContentHandler(PageViewFragmentInternal parentFragment, CommunicationBridge bridge, ObservableWebView webview, LinkHandler linkHandler, ViewGroup hidingView, PageTitle pageTitle) { this.parentFragment = parentFragment; this.bridge = bridge; this.webView = webview; this.linkHandler = linkHandler; this.pageTitle = pageTitle; activity = parentFragment.getActivity(); app = (WikipediaApp) activity.getApplicationContext(); displayDensity = activity.getResources().getDisplayMetrics().density; bottomContentContainer = hidingView; webview.addOnScrollChangeListener(this); webview.addOnContentHeightChangedListener(this); pageLastUpdatedText = (TextView) bottomContentContainer.findViewById(R.id.page_last_updated_text); pageLicenseText = (TextView) bottomContentContainer.findViewById(R.id.page_license_text); readMoreContainer = bottomContentContainer.findViewById(R.id.read_more_container); readMoreList = (ListView) bottomContentContainer.findViewById(R.id.read_more_list); // set up pass-through scroll functionality for the ListView readMoreList.setOnTouchListener(new View.OnTouchListener() { private int touchSlop = ViewConfiguration.get(readMoreList.getContext()).getScaledTouchSlop(); private boolean slopReached; private boolean doingSlopEvent; private boolean isPressed = false; private float startY; private float amountScrolled; @Override/*w ww . j av a 2 s .com*/ public boolean onTouch(View v, MotionEvent event) { int action = event.getActionMasked() & MotionEvent.ACTION_MASK; switch (action) { case MotionEvent.ACTION_DOWN: isPressed = true; startY = event.getY(); amountScrolled = 0; slopReached = false; break; case MotionEvent.ACTION_MOVE: if (isPressed && !doingSlopEvent) { int contentHeight = (int) (webView.getContentHeight() * displayDensity); int maxScroll = contentHeight - webView.getScrollY() - webView.getHeight(); int scrollAmount = Math.min((int) (startY - event.getY()), maxScroll); // manually scroll the WebView that's underneath us... webView.scrollBy(0, scrollAmount); amountScrolled += scrollAmount; if (Math.abs(amountScrolled) > touchSlop && !slopReached) { slopReached = true; // send an artificial Move event that scrolls it by an amount // that's greater than the touch slop, so that the currently // highlighted item is unselected. MotionEvent moveEvent = MotionEvent.obtain(event); moveEvent.setLocation(event.getX(), event.getY() + touchSlop * 2); doingSlopEvent = true; readMoreList.dispatchTouchEvent(moveEvent); doingSlopEvent = false; } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: isPressed = false; break; default: break; } return false; } }); funnel = new SuggestedPagesFunnel(app, pageTitle.getSite()); // preload the display density, since it will be used in a lot of places displayDensity = activity.getResources().getDisplayMetrics().density; // hide ourselves by default hide(); }
From source file:com.fortysevendeg.android.swipelistview.SwipeRefreshListViewTouchListener.java
/** * @see View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent) *///ww w . ja v a 2s. c o m @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (!isSwipeEnabled()) { return false; } mViewWidth = mSwipeListView.getWidth(); switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: { return actionDown(view, motionEvent); } case MotionEvent.ACTION_UP: { actionUp(motionEvent); if (mRefreshSwipeListener != null && mSwipeListView.isListAtTop()) { mRefreshSwipeListener.setScroll(false); } break; } case MotionEvent.ACTION_MOVE: { if (mVelocityTracker == null || mPaused || mDownPosition == ListView.INVALID_POSITION) { break; } mVelocityTracker.addMovement(motionEvent); mVelocityTracker.computeCurrentVelocity(1000); float velocityX = Math.abs(mVelocityTracker.getXVelocity()); float velocityY = Math.abs(mVelocityTracker.getYVelocity()); float deltaX = motionEvent.getRawX() - mDownX; float deltaMode = Math.abs(deltaX); int swipeMode = mSwipeMode; int changeSwipeMode = mSwipeListView.changeSwipeMode(mDownPosition); if (changeSwipeMode >= 0) { swipeMode = changeSwipeMode; } if (swipeMode == SwipeListView.SWIPE_MODE_NONE) { deltaMode = 0; } else if (swipeMode != SwipeListView.SWIPE_MODE_BOTH) { if (mOpened.get(mDownPosition)) { if (swipeMode == SwipeListView.SWIPE_MODE_LEFT && deltaX < 0) { deltaMode = 0; } else if (swipeMode == SwipeListView.SWIPE_MODE_RIGHT && deltaX > 0) { deltaMode = 0; } } else { if (swipeMode == SwipeListView.SWIPE_MODE_LEFT && deltaX > 0) { deltaMode = 0; } else if (swipeMode == SwipeListView.SWIPE_MODE_RIGHT && deltaX < 0) { deltaMode = 0; } } } if (deltaMode > mSlop && mSwipeCurrentAction == SwipeListView.SWIPE_ACTION_NONE && velocityY < velocityX) { mSwiping = true; if (mRefreshSwipeListener != null) { mRefreshSwipeListener.setScroll(true); } boolean swipingRight = (deltaX > 0); if (mOpened.get(mDownPosition)) { mSwipeListView.onStartClose(mDownPosition, swipingRight); mSwipeCurrentAction = SwipeListView.SWIPE_ACTION_REVEAL; } else { if (swipingRight && mSwipeActionRight == SwipeListView.SWIPE_ACTION_DISMISS) { mSwipeCurrentAction = SwipeListView.SWIPE_ACTION_DISMISS; } else if (!swipingRight && mSwipeActionLeft == SwipeListView.SWIPE_ACTION_DISMISS) { mSwipeCurrentAction = SwipeListView.SWIPE_ACTION_DISMISS; } else if (swipingRight && mSwipeActionRight == SwipeListView.SWIPE_ACTION_CHECK) { mSwipeCurrentAction = SwipeListView.SWIPE_ACTION_CHECK; } else if (!swipingRight && mSwipeActionLeft == SwipeListView.SWIPE_ACTION_CHECK) { mSwipeCurrentAction = SwipeListView.SWIPE_ACTION_CHECK; } else { mSwipeCurrentAction = SwipeListView.SWIPE_ACTION_REVEAL; } mSwipeListView.onStartOpen(mDownPosition, mSwipeCurrentAction, swipingRight); } mSwipeListView.requestDisallowInterceptTouchEvent(true); MotionEvent cancelEvent = MotionEvent.obtain(motionEvent); cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (MotionEventCompat .getActionIndex(motionEvent) << MotionEventCompat.ACTION_POINTER_INDEX_SHIFT)); mSwipeListView.onTouchEvent(cancelEvent); } if (mSwiping) { if (mOpened.get(mDownPosition)) { deltaX += mOpenedRight.get(mDownPosition) ? mViewWidth - mRightOffset : -mViewWidth + mLeftOffset; } move(deltaX); return true; } break; } } return false; }
From source file:com.malinskiy.superrecyclerview.swipe.SwipeDismissRecyclerViewTouchListener.java
private void caseMotionActionMove(MotionEvent motionEvent) { mVelocityTracker.addMovement(motionEvent); float deltaX = motionEvent.getRawX() - mDownX; float deltaY = motionEvent.getRawY() - mDownY; if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) { mSwiping = true;//from ww w . ja v a 2s .c o m mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop); mRecyclerView.requestDisallowInterceptTouchEvent(true); // Cancel ListView's touch (un-highlighting the item) MotionEvent cancelEvent = MotionEvent.obtain(motionEvent); cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (MotionEventCompat .getActionIndex(motionEvent) << MotionEventCompat.ACTION_POINTER_INDEX_SHIFT)); mRecyclerView.onTouchEvent(cancelEvent); cancelEvent.recycle(); if (mSwiping) { setTranslationX(mDownView, deltaX - mSwipingSlop); setAlpha(mDownView, Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / mViewWidth))); } } }
From source file:com.codingfeel.sm.views.superrecyclerview.swipe.SwipeDismissRecyclerViewTouchListener.java
private void caseMotionActionMove(MotionEvent motionEvent) { mVelocityTracker.addMovement(motionEvent); float deltaX = motionEvent.getRawX() - mDownX; float deltaY = motionEvent.getRawY() - mDownY; if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) { mSwiping = true;/*from w ww . j av a 2 s . c o m*/ int mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop); mRecyclerView.requestDisallowInterceptTouchEvent(true); // Cancel ListView's touch (un-highlighting the item) MotionEvent cancelEvent = MotionEvent.obtain(motionEvent); cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (MotionEventCompat .getActionIndex(motionEvent) << MotionEventCompat.ACTION_POINTER_INDEX_SHIFT)); mRecyclerView.onTouchEvent(cancelEvent); cancelEvent.recycle(); if (mSwiping) { setTranslationX(mDownView, deltaX - mSwipingSlop); setAlpha(mDownView, Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / mViewWidth))); } } }
From source file:it.sephiroth.android.library.imagezoom.ScaleGestureDetector.java
public boolean onTouchEvent(final MotionEvent event) { final int action = event.getAction(); final boolean handled = true; if (!mGestureInProgress) { switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_POINTER_DOWN: { // We have a new multi-finger gesture // as orientation can change, query the metrics in touch // down final DisplayMetrics metrics = mContext.getResources().getDisplayMetrics(); mRightSlopEdge = metrics.widthPixels - mEdgeSlop; mBottomSlopEdge = metrics.heightPixels - mEdgeSlop; // Be paranoid in case we missed an event reset();// w w w . ja v a2 s .c o m mPrevEvent = MotionEvent.obtain(event); mTimeDelta = 0; setContext(event); // Check if we have a sloppy gesture. If so, delay // the beginning of the gesture until we're sure that's // what the user wanted. Sloppy gestures can happen if the // edge of the user's hand is touching the screen, for // example. final float edgeSlop = mEdgeSlop; final float rightSlop = mRightSlopEdge; final float bottomSlop = mBottomSlopEdge; final float x0 = event.getRawX(); final float y0 = event.getRawY(); final float x1 = getRawX(event, 1); final float y1 = getRawY(event, 1); final boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlop || y0 > bottomSlop; final boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlop || y1 > bottomSlop; if (p0sloppy && p1sloppy) { mFocusX = -1; mFocusY = -1; mSloppyGesture = true; } else if (p0sloppy) { mFocusX = MotionEventCompat.getX(event, 1); mFocusY = MotionEventCompat.getY(event, 1); mSloppyGesture = true; } else if (p1sloppy) { mFocusX = MotionEventCompat.getX(event, 0); mFocusY = MotionEventCompat.getY(event, 0); mSloppyGesture = true; } else { mGestureInProgress = mListener.onScaleBegin(this); } } break; case MotionEvent.ACTION_MOVE: if (mSloppyGesture) { // Initiate sloppy gestures if we've moved outside of // the slop area. final float edgeSlop = mEdgeSlop; final float rightSlop = mRightSlopEdge; final float bottomSlop = mBottomSlopEdge; final float x0 = event.getRawX(); final float y0 = event.getRawY(); final float x1 = getRawX(event, 1); final float y1 = getRawY(event, 1); final boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlop || y0 > bottomSlop; final boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlop || y1 > bottomSlop; if (p0sloppy && p1sloppy) { mFocusX = -1; mFocusY = -1; } else if (p0sloppy) { mFocusX = MotionEventCompat.getX(event, 1); mFocusY = MotionEventCompat.getY(event, 1); } else if (p1sloppy) { mFocusX = MotionEventCompat.getX(event, 0); mFocusY = MotionEventCompat.getY(event, 0); } else { mSloppyGesture = false; mGestureInProgress = mListener.onScaleBegin(this); } } break; case MotionEvent.ACTION_POINTER_UP: if (mSloppyGesture) { // Set focus point to the remaining finger final int id = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT == 0 ? 1 : 0; mFocusX = event.getX(id); mFocusY = event.getY(id); } break; } } else { // Transform gesture in progress - attempt to handle it switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_POINTER_UP: // Gesture ended setContext(event); // Set focus point to the remaining finger final int id = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT == 0 ? 1 : 0; mFocusX = event.getX(id); mFocusY = event.getY(id); if (!mSloppyGesture) { mListener.onScaleEnd(this); } reset(); break; case MotionEvent.ACTION_CANCEL: if (!mSloppyGesture) { mListener.onScaleEnd(this); } reset(); break; case MotionEvent.ACTION_MOVE: setContext(event); // Only accept the event if our relative pressure is within // a certain limit - this can help filter shaky data as a // finger is lifted. if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) { final boolean updatePrevious = mListener.onScale(this); if (updatePrevious) { mPrevEvent.recycle(); mPrevEvent = MotionEvent.obtain(event); } } break; } } return handled; }