public static void velocityTrackerPointerUpCleanUpIfNecessary(MotionEvent ev, VelocityTracker tracker) { // Check the dot product of current velocities. // If the pointer that left was opposing another velocity vector, clear. tracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); final int upIndex = ev.getActionIndex(); final int id1 = ev.getPointerId(upIndex); final float x1 = tracker.getXVelocity(id1); final float y1 = tracker.getYVelocity(id1); for (int i = 0, count = ev.getPointerCount(); i < count; i++) { if (i == upIndex) continue; final int id2 = ev.getPointerId(i); final float x = x1 * tracker.getXVelocity(id2); final float y = y1 * tracker.getYVelocity(id2); final float dot = x + y; if (dot < 0) { tracker.clear(); break; } } }
/** * Start a fake drag of the pager. * * @return true if the fake drag began successfully, false if it could not be started. */ public boolean beginFakeDrag() { if (mIsBeingDragged) { return false; } mFakeDragging = true; setScrollState(SCROLL_STATE_DRAGGING); if (isHorizontal()) { mInitialMotionX = mLastMotionX = 0; } else { mInitialMotionY = mLastMotionY = 0; } if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } else { mVelocityTracker.clear(); } final long time = SystemClock.uptimeMillis(); final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0); mVelocityTracker.addMovement(ev); ev.recycle(); mFakeDragBeginTime = time; return true; }
/** * Start a fake drag of the pager. * <p/> * <p>A fake drag can be useful if you want to synchronize the motion of the ViewPager * with the touch scrolling of another view, while still letting the ViewPager * control the snapping motion and fling behavior. (e.g. parallax-scrolling tabs.) * Call {@link #fakeDragBy(float)} to simulate the actual drag motion. Call * {@link #endFakeDrag()} to complete the fake drag and fling as necessary. * <p/> * <p>During a fake drag the ViewPager will ignore all touch events. If a real drag * is already in progress, this method will return false. * * @return true if the fake drag began successfully, false if it could not be started. * @see #fakeDragBy(float) * @see #endFakeDrag() */ public boolean beginFakeDrag() { if (mIsBeingDragged) { return false; } mFakeDragging = true; setScrollState(SCROLL_STATE_DRAGGING); mInitialMotionY = mLastMotionY = 0; if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } else { mVelocityTracker.clear(); } final long time = SystemClock.uptimeMillis(); final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0); mVelocityTracker.addMovement(ev); ev.recycle(); mFakeDragBeginTime = time; return true; }
/** * End a fake drag of the pager. * * @see #beginFakeDrag() * @see #fakeDragBy(float) */ public void endFakeDrag() { if (!mFakeDragging) { throw new IllegalStateException("No fake drag in progress. Call beginFakeDrag first."); } final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getYVelocity( velocityTracker, mActivePointerId); mPopulatePending = true; final int height = getClientHeight(); final int scrollY = getScrollY(); final ItemInfo ii = infoForCurrentScrollPosition(); final int currentPage = ii.position; final float pageOffset = (((float) scrollY / height) - ii.offset) / ii.heightFactor; final int totalDelta = (int) (mLastMotionY - mInitialMotionY); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); endDrag(); mFakeDragging = false; }
/** * Start a fake drag of the pager. * <p/> * <p>A fake drag can be useful if you want to synchronize the motion of the ViewPager * with the touch scrolling of another view, while still letting the ViewPager * control the snapping motion and fling behavior. (e.g. parallax-scrolling tabs.) * Call {@link #fakeDragBy(float)} to simulate the actual drag motion. Call * {@link #endFakeDrag()} to complete the fake drag and fling as necessary. * <p/> * <p>During a fake drag the ViewPager will ignore all touch events. If a real drag * is already in progress, this method will return false. * * @return true if the fake drag began successfully, false if it could not be started. * @see #fakeDragBy(float) * @see #endFakeDrag() */ public boolean beginFakeDrag() { if (mIsBeingDragged) { return false; } mFakeDragging = true; setScrollState(SCROLL_STATE_DRAGGING); if (isHorizontalDirection()) { mInitialMotionX = mLastMotionX = 0; } else if (isVerticalDirection()) { mInitialMotionY = mLastMotionY = 0; } if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } else { mVelocityTracker.clear(); } final long time = SystemClock.uptimeMillis(); final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0); mVelocityTracker.addMovement(ev); ev.recycle(); mFakeDragBeginTime = time; return true; }
private void endFakeDragHorizontally() { if (mAdapter != null) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getXVelocity( velocityTracker, mActivePointerId); mPopulatePending = true; final int width = getClientWidth(); final int scrollX = getScrollX(); final ItemInfo ii = infoForCurrentScrollPosition(); final int currentPage = ii.position; final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor; final int totalDelta = (int) (mLastMotionX - mInitialMotionX); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); } endDrag(); mFakeDragging = false; }
private void endFakeDragVertically() { if (mAdapter != null) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getYVelocity( velocityTracker, mActivePointerId); mPopulatePending = true; final int height = getClientHeight(); final int scrollY = getScrollY(); final ItemInfo ii = infoForCurrentScrollPosition(); final int currentPage = ii.position; final float pageOffset = (((float) scrollY / height) - ii.offset) / ii.heightFactor; final int totalDelta = (int) (mLastMotionY - mInitialMotionY); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); } endDrag(); mFakeDragging = false; }
public ResolverDrawerLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ResolverDrawerLayout, defStyleAttr, 0); mMaxWidth = a.getDimensionPixelSize(R.styleable.ResolverDrawerLayout_android_maxWidth, -1); mMaxCollapsedHeight = a.getDimensionPixelSize( R.styleable.ResolverDrawerLayout_maxCollapsedHeight, 0); mMaxCollapsedHeightSmall = a.getDimensionPixelSize( R.styleable.ResolverDrawerLayout_maxCollapsedHeightSmall, mMaxCollapsedHeight); a.recycle(); mScrollIndicatorDrawable = context.getDrawable(R.drawable.scroll_indicator_material); mScroller = new OverScroller(context, AnimationUtils.loadInterpolator(context, android.R.interpolator.decelerate_quint)); mVelocityTracker = VelocityTracker.obtain(); final ViewConfiguration vc = ViewConfiguration.get(context); mTouchSlop = vc.getScaledTouchSlop(); mMinFlingVelocity = vc.getScaledMinimumFlingVelocity(); setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); }
private float getXVelocity() { float xVelocity = 0; Class viewpagerClass = ViewPager.class; try { Field velocityTrackerField = viewpagerClass.getDeclaredField("mVelocityTracker"); velocityTrackerField.setAccessible(true); VelocityTracker velocityTracker = (VelocityTracker) velocityTrackerField.get(this); Field activePointerIdField = viewpagerClass.getDeclaredField("mActivePointerId"); activePointerIdField.setAccessible(true); Field maximumVelocityField = viewpagerClass.getDeclaredField("mMaximumVelocity"); maximumVelocityField.setAccessible(true); int maximumVelocity = maximumVelocityField.getInt(this); velocityTracker.computeCurrentVelocity(1000, maximumVelocity); xVelocity = VelocityTrackerCompat.getXVelocity(velocityTracker, activePointerIdField.getInt(this)); } catch (Exception e) { } return xVelocity; }
private void onTouchRelease() { final StackCardsView.LayoutParams lp = (StackCardsView.LayoutParams) mTouchChild.getLayoutParams(); if (lp.fastDismissAllowed) { final VelocityTracker velocityTracker2 = mVelocityTracker; velocityTracker2.computeCurrentVelocity(1000, mMaxVelocity); float xv = velocityTracker2.getXVelocity(mActivePointerId); float yv = velocityTracker2.getYVelocity(mActivePointerId); if (doFastDisappear(xv, yv)) { resetTouch(); return; } } if (isDistanceAllowDismiss() && isDirectionAllowDismiss()) { doSlowDisappear(); } else { animateToInitPos(); } resetTouch(); mSwipeView.onCoverStatusChanged(isCoverIdle()); }
@Override public boolean onTouchEvent(MotionEvent event) { if (mVirtualCount == 0 || !isEnabled()) { return super.onTouchEvent(event); } if (event.getAction() == MotionEvent.ACTION_DOWN && event.getEdgeFlags() != 0) { return false; } if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); final int action = event.getAction() & MotionEventCompat.ACTION_MASK; if (action == MotionEvent.ACTION_MOVE) { handleTouchActionMove(event); } else { if (action == MotionEvent.ACTION_DOWN) { handleTouchActionDown(event); } if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { handleTouchActionUp(event); } } return true; }
@Override public boolean onTouchEvent(MotionEvent event) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); switch (event.getAction()) { case MotionEvent.ACTION_CANCEL: actionCancel(event); break; case MotionEvent.ACTION_DOWN: actionDown(event); break; case MotionEvent.ACTION_MOVE: actionMove(event); break; case MotionEvent.ACTION_UP: actionUp(event); break; default: break; } invalidateView(); return true; }
/** * Start a fake drag of the pager. * * <p>A fake drag can be useful if you want to synchronize the motion of the ViewPager * with the touch scrolling of another view, while still letting the ViewPager * control the snapping motion and fling behavior. (e.g. parallax-scrolling tabs.) * Call {@link #fakeDragBy(float)} to simulate the actual drag motion. Call * {@link #endFakeDrag()} to complete the fake drag and fling as necessary. * * <p>During a fake drag the ViewPager will ignore all touch events. If a real drag * is already in progress, this method will return false. * * @return true if the fake drag began successfully, false if it could not be started. * * @see #fakeDragBy(float) * @see #endFakeDrag() */ public boolean beginFakeDrag() { if (mIsBeingDragged) { return false; } mFakeDragging = true; setScrollState(SCROLL_STATE_DRAGGING); mInitialMotionX = mLastMotionX = 0; if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } else { mVelocityTracker.clear(); } final long time = SystemClock.uptimeMillis(); final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0); mVelocityTracker.addMovement(ev); ev.recycle(); mFakeDragBeginTime = time; return true; }
/** * End a fake drag of the pager. * * @see #beginFakeDrag() * @see #fakeDragBy(float) */ public void endFakeDrag() { if (!mFakeDragging) { throw new IllegalStateException("No fake drag in progress. Call beginFakeDrag first."); } final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getXVelocity( velocityTracker, mActivePointerId); mPopulatePending = true; final int width = getClientWidth(); final int scrollX = getScrollX(); final ItemInfo ii = infoForCurrentScrollPosition(); final int currentPage = ii.position; final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor; final int totalDelta = (int) (mLastMotionX - mInitialMotionX); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); endDrag(); mFakeDragging = false; }
public boolean beginFakeDrag() { if (mIsBeingDragged) { return false; } mFakeDragging = true; setScrollState(SCROLL_STATE_DRAGGING); mInitialMotionX = mLastMotionX = 0; if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } else { mVelocityTracker.clear(); } final long time = SystemClock.uptimeMillis(); final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0); mVelocityTracker.addMovement(ev); ev.recycle(); mFakeDragBeginTime = time; return true; }
public void endFakeDrag() { if (this.mFakeDragging) { if (this.mAdapter != null) { VelocityTracker velocityTracker = this.mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, (float) this.mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, this.mActivePointerId); this.mPopulatePending = true; int width = getClientWidth(); int scrollX = getScrollX(); ItemInfo ii = infoForCurrentScrollPosition(); setCurrentItemInternal(determineTargetPage(ii.position, ((((float) scrollX) / ((float) width)) - ii.offset) / ii.widthFactor, initialVelocity, (int) (this.mLastMotionX - this.mInitialMotionX)), true, true, initialVelocity); } endDrag(); this.mFakeDragging = false; return; } throw new IllegalStateException("No fake drag in progress. Call beginFakeDrag first."); }
public boolean beginFakeDrag() { if (this.mIsBeingDragged) { return false; } this.mFakeDragging = true; setScrollState(1); this.mLastMotionX = 0.0f; this.mInitialMotionX = 0.0f; if (this.mVelocityTracker == null) { this.mVelocityTracker = VelocityTracker.obtain(); } else { this.mVelocityTracker.clear(); } long time = SystemClock.uptimeMillis(); MotionEvent ev = MotionEvent.obtain(time, time, 0, 0.0f, 0.0f, 0); this.mVelocityTracker.addMovement(ev); ev.recycle(); this.mFakeDragBeginTime = time; return true; }
public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) { if (!child.isShown()) { return false; } int action = MotionEventCompat.getActionMasked(event); if (this.mState == 1 && action == 0) { return true; } this.mViewDragHelper.processTouchEvent(event); if (action == 0) { reset(); } if (this.mVelocityTracker == null) { this.mVelocityTracker = VelocityTracker.obtain(); } this.mVelocityTracker.addMovement(event); if (action != 2 || Math.abs(((float) this.mInitialY) - event.getY()) <= ((float) this.mViewDragHelper.getTouchSlop())) { return true; } this.mViewDragHelper.captureChildView(child, event.getPointerId(event.getActionIndex())); return true; }
public BannerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setOnClickListener(this); mScroller = new Scroller(context); mVelocityTracker = VelocityTracker.obtain(); final ViewConfiguration configuration = ViewConfiguration.get(context); final float density = context.getResources().getDisplayMetrics().density; mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.BannerView); mHorizontalOffset = array.getDimension(R.styleable.BannerView_horizontal_offset, 0); mVerticalOffset = array.getDimension(R.styleable.BannerView_vertical_offset, 0); duration = array.getInt(R.styleable.BannerView_scroll_duration, 500); array.recycle(); }
public boolean onTouchDown(MotionEvent event) { final float x = event.getX(); final float y= event.getY(); if (doesLocationIntercept(x, y)) { this.touchOverride = true; this.overrideX = x; this.overrideY = y; this.overrideDeltaX = currentX - x; this.overrideDeltaY = currentY - y; velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(event); return true; } else { return false; } }
/** * Handles, when a drag gesture has been started. * * @param event * The motion event, which started the drag gesture, as an instance of the class {@link * MotionEvent}. The motion event may not be null */ private void handleDown(@NonNull final MotionEvent event) { pointerId = event.getPointerId(0); if (velocityTracker == null) { velocityTracker = VelocityTracker.obtain(); } else { velocityTracker.clear(); } velocityTracker.addMovement(event); onDown(event); }
private void prepareTracking(int position) { mTracking = true; mVelocityTracker = VelocityTracker.obtain(); boolean opening = !mExpanded; if (opening) { mAnimatedAcceleration = mMaximumAcceleration; mAnimatedVelocity = mMaximumMajorVelocity; if (mInvert) mAnimationPosition = mTopOffset; else mAnimationPosition = mBottomOffset + (mVertical ? getHeight() - mHandleHeight : getWidth() - mHandleWidth); moveHandle((int) mAnimationPosition); mAnimating = true; mHandler.removeMessages(MSG_ANIMATE); long now = SystemClock.uptimeMillis(); mAnimationLastTime = now; mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION; mAnimating = true; } else { if (mAnimating) { mAnimating = false; mHandler.removeMessages(MSG_ANIMATE); } moveHandle(position); } }
SwipeHelper(int swipeDirection, Callback callback, Context context) { mCallback = callback; mHandler = new Handler(); mSwipeDirection = swipeDirection; mVelocityTracker = VelocityTracker.obtain(); mDensityScale = context.getResources().getDisplayMetrics().density; mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop(); mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press! mFalsingThreshold = context.getResources().getDimensionPixelSize( R.dimen.swipe_helper_falsing_threshold); mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f); }
/** * @param event 向VelocityTracker添加MotionEvent * @see VelocityTracker#obtain() * @see VelocityTracker#addMovement(MotionEvent) */ private void acquireVelocityTracker(final MotionEvent event) { if (null == mVelocityTracker) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); }
public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); float xPosition = event.getX(); if (this.velocityTracker == null) { this.velocityTracker = VelocityTracker.obtain(); } this.velocityTracker.addMovement(event); switch (action) { case 0: this.isActionUp = false; this.scroller.forceFinished(true); if (this.animator != null) { this.animator.cancel(); break; } break; case 1: case 3: this.isActionUp = true; this.f = true; countVelocityTracker(event); return false; case 2: this.isActionUp = false; float off = xPosition - this.mLastX; if ((this.moveX > this.maxRightOffset || off >= 0.0f) && (this.moveX < this .maxLeftOffset || off <= 0.0f)) { this.moveX += off; postInvalidate(); break; } } this.mLastX = xPosition; return true; }
/** */ @Override float computeOverScroll(int scrollX, int scrollY, boolean clampedX, boolean clampedY, VelocityTracker tracker, int units) { if (scrollY != 0 && clampedY) { return tracker.getYVelocity() / (units * 0.05f); } return 0; }
@Override public boolean onTouchEvent(MotionEvent event) { isTouch = true; if (event.getPointerCount() >= 2) return false; if (mAdapter == null) return super.onTouchEvent(event); int count = mAdapter.getCount(); if (count <= 1) return super.onTouchEvent(event); float x = event.getRawX(); mVelocityTracker.addMovement(event); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: if (!mScroller.isFinished()) { // 如果上次的调用没有执行完就取消。 return false; } mLastX = x; return true; case MotionEvent.ACTION_MOVE: requestDisallowInterceptTouchEvent(true); int dxMove = (int) (mLastX - x); mTotalDx += dxMove; onScrollBy(dxMove); mLastX = x; return true; case MotionEvent.ACTION_UP: isTouch = false; if (Math.abs(mTotalDx) <= 10) performClick(); case MotionEvent.ACTION_CANCEL: { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); mXVelocity = velocityTracker.getXVelocity(); isTouch = false; scrollToItem(); scrollFinish(count); break; } } return super.onTouchEvent(event); }
private void init() { WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); windowWidth = wm.getDefaultDisplay().getWidth();//获取屏幕宽度 halfWindowWidth = windowWidth / 2; oneThirdWindowWidth = windowWidth / visualCount; mVelocityTracker = VelocityTracker.obtain(); }
@Override public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) { if (!child.isShown()) { return false; } int action = MotionEventCompat.getActionMasked(event); if (mState == STATE_DRAGGING && action == MotionEvent.ACTION_DOWN) { return true; } mViewDragHelper.processTouchEvent(event); // Record the velocity if (action == MotionEvent.ACTION_DOWN) { reset(); } if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); // The ViewDragHelper tries to capture only the top-most View. We have to explicitly tell it // to capture the bottom sheet in case it is not captured and the touch slop is passed. if (action == MotionEvent.ACTION_MOVE && !mIgnoreEvents) { if (Math.abs(mInitialY - event.getY()) > mViewDragHelper.getTouchSlop()) { mViewDragHelper.captureChildView(child, event.getPointerId(event.getActionIndex())); } } return !mIgnoreEvents; }
protected float getXVelocity(VelocityTracker velocityTracker) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { return velocityTracker.getXVelocity(mActivePointerId); } return velocityTracker.getXVelocity(); }
private void initOrResetVelocityTracker() { if (this.mVelocityTracker == null) { this.mVelocityTracker = VelocityTracker.obtain(); } else { this.mVelocityTracker.clear(); } }
private void touchBegan(MotionEvent event) { endAnimation(); float x = event.getX(); mTouchStartX = x; mTouchStartY = event.getY(); mStartTime = AnimationUtils.currentAnimationTimeMillis(); mStartOffset = mOffset; mTouchMoved = false; mTouchStartPos = (mTouchStartY / mHeight) * MOVE_POS_MULTIPLE - 5; mTouchStartPos /= 2; mVelocity = VelocityTracker.obtain(); mVelocity.addMovement(event); // float x = event.getX(); // mTouchStartX = x; // mTouchStartY = event.getY(); // mStartTime = AnimationUtils.currentAnimationTimeMillis(); // mStartOffset = mOffset; // // mTouchMoved = false; // // mTouchStartPos = (x / mWidth) * MOVE_POS_MULTIPLE - 5; // mTouchStartPos /= 2; // // mVelocity = VelocityTracker.obtain(); // mVelocity.addMovement(event); }