public override bool OnTouchEvent(MotionEvent ev) { MotionEventActions action = ev.Action; if (mReturningToStart && action == MotionEventActions.Down) { mReturningToStart = false; } if (!Enabled || mReturningToStart || canChildScrollUp()) { // Fail fast if we're not in a state where a swipe is possible return(false); } switch (action) { case MotionEventActions.Down: mActivePointerId = ev.GetPointerId(0); mIsBeingDragged = false; break; case MotionEventActions.Move: int pointerIndex = ev.FindPointerIndex(mActivePointerId); if (pointerIndex < 0) { Log.Error(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); return(false); } float y = ev.GetY(pointerIndex); float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; if (mIsBeingDragged) { mProgress.showArrow(true); float originalDragPercent = overscrollTop / mTotalDragDistance; if (originalDragPercent < 0) { return(false); } float dragPercent = System.Math.Min(1f, System.Math.Abs(originalDragPercent)); float adjustedPercent = (float)System.Math.Max(dragPercent - .4, 0) * 5 / 3; float extraOS = System.Math.Abs(overscrollTop) - mTotalDragDistance; float slingshotDist = mUsingCustomStart ? mSpinnerFinalOffset - mOriginalOffsetTop : mSpinnerFinalOffset; float tensionSlingshotPercent = System.Math.Max(0, System.Math.Min(extraOS, slingshotDist * 2) / slingshotDist); float tensionPercent = (float)((tensionSlingshotPercent / 4) - System.Math.Pow( (tensionSlingshotPercent / 4), 2)) * 2f; float extraMove = (slingshotDist) * tensionPercent * 2; int targetY = mOriginalOffsetTop + (int)((slingshotDist * dragPercent) + extraMove); // where 1.0f is a full circle if (mCircleView.Visibility != ViewStates.Visible) { mCircleView.Visibility = ViewStates.Visible; } if (!mScale) { ViewCompat.SetScaleX(mCircleView, 1f); ViewCompat.SetScaleY(mCircleView, 1f); } if (overscrollTop < mTotalDragDistance) { if (mScale) { setAnimationProgress(overscrollTop / mTotalDragDistance); } if (mProgress.Alpha > STARTING_PROGRESS_ALPHA && !isAnimationRunning(mAlphaStartAnimation)) { // Animate the alpha startProgressAlphaStartAnimation(); } float strokeStart = adjustedPercent * .8f; mProgress.setStartEndTrim(0f, System.Math.Min(MAX_PROGRESS_ANGLE, strokeStart)); mProgress.setArrowScale(System.Math.Min(1f, adjustedPercent)); } else { if (mProgress.Alpha < MAX_ALPHA && !isAnimationRunning(mAlphaMaxAnimation)) { // Animate the alpha startProgressAlphaMaxAnimation(); } } float rotation = (-0.25f + .4f * adjustedPercent + tensionPercent * 2) * .5f; mProgress.setProgressRotation(rotation); setTargetOffsetTopAndBottom(targetY - mCurrentTargetOffsetTop, true /* requires update */); } break; //case MotionEventActions.Down: // int index = ev.ActionIndex; // mActivePointerId = ev.GetPointerId(index); // break; case MotionEventActions.PointerUp: onSecondaryPointerUp(ev); break; case MotionEventActions.Up: case MotionEventActions.Cancel: { if (mActivePointerId == INVALID_POINTER) { if (action == MotionEventActions.Up) { Log.Error(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id."); } return(false); } int pointerIndex0 = ev.FindPointerIndex(mActivePointerId); float y0 = ev.GetY(pointerIndex0); float overscrollTop0 = (y0 - mInitialMotionY) * DRAG_RATE; mIsBeingDragged = false; if (overscrollTop0 > mTotalDragDistance) { setRefreshing(true, true /* notify */); } else { // cancel refresh mRefreshing = false; mProgress.setStartEndTrim(0f, 0f); IAnimationListener listener = null; if (!mScale) { listener = new CustomCancelListener(this); } animateOffsetToStartPosition(mCurrentTargetOffsetTop, listener); mProgress.showArrow(false); } mActivePointerId = INVALID_POINTER; return(false); } } return(true); }
public override bool OnTouchEvent(MotionEvent ev) { var action = ev.Action; if (_returningToStart && action == MotionEventActions.Down) { _returningToStart = false; } if (!Enabled || _returningToStart || CanChildScrollUp()) { // Fail fast if we're not in a state where a swipe is possible return(false); } switch (action) { case MotionEventActions.Down: _activePointerId = ev.GetPointerId(0); _isBeingDragged = false; break; case MotionEventActions.Move: var pointerIndex = ev.FindPointerIndex(_activePointerId); if (pointerIndex < 0) { Log.Error(LogTag, "Got ACTION_MOVE event but have an invalid active pointer id."); return(false); } var y = ev.GetY(pointerIndex); var overscrollTop = (y - _initialMotionY) * DragRate; if (_isBeingDragged) { _progress.ShowArrow(true); var originalDragPercent = overscrollTop / _totalDragDistance; if (originalDragPercent < 0) { return(false); } var dragPercent = System.Math.Min(1f, System.Math.Abs(originalDragPercent)); var adjustedPercent = (float)System.Math.Max(dragPercent - .4, 0) * 5 / 3; var extraOS = System.Math.Abs(overscrollTop) - _totalDragDistance; var slingshotDist = _usingCustomStart ? _spinnerFinalOffset - OriginalOffsetTop : _spinnerFinalOffset; var tensionSlingshotPercent = System.Math.Max(0, System.Math.Min(extraOS, slingshotDist * 2) / slingshotDist); var tensionPercent = (float)((tensionSlingshotPercent / 4) - System.Math.Pow( (tensionSlingshotPercent / 4), 2)) * 2f; var extraMove = (slingshotDist) * tensionPercent * 2; var targetY = OriginalOffsetTop + (int)((slingshotDist * dragPercent) + extraMove); // where 1.0f is a full circle if (_circleView.Visibility != ViewStates.Visible) { _circleView.Visibility = ViewStates.Visible; } if (!_scale) { ViewCompat.SetScaleX(_circleView, 1f); ViewCompat.SetScaleY(_circleView, 1f); } if (overscrollTop < _totalDragDistance) { if (_scale) { SetAnimationProgress(overscrollTop / _totalDragDistance); } if (_progress.Alpha > StartingProgressAlpha && !IsAnimationRunning(_alphaStartAnimation)) { // Animate the alpha StartProgressAlphaStartAnimation(); } var strokeStart = adjustedPercent * .8f; _progress.SetStartEndTrim(0f, System.Math.Min(MaxProgressAngle, strokeStart)); _progress.SetArrowScale(System.Math.Min(1f, adjustedPercent)); } else { if (_progress.Alpha < MaxAlpha && !IsAnimationRunning(_alphaMaxAnimation)) { // Animate the alpha StartProgressAlphaMaxAnimation(); } } var rotation = (-0.25f + .4f * adjustedPercent + tensionPercent * 2) * .5f; _progress.SetProgressRotation(rotation); SetTargetOffsetTopAndBottom(targetY - _currentTargetOffsetTop, true /* requires update */); } break; //case MotionEventActions.Down: // int index = ev.ActionIndex; // mActivePointerId = ev.GetPointerId(index); // break; case MotionEventActions.PointerUp: OnSecondaryPointerUp(ev); break; case MotionEventActions.Up: case MotionEventActions.Cancel: { if (_activePointerId == InvalidPointer) { if (action == MotionEventActions.Up) { Log.Error(LogTag, "Got ACTION_UP event but don't have an active pointer id."); } return(false); } var pointerIndex0 = ev.FindPointerIndex(_activePointerId); var y0 = ev.GetY(pointerIndex0); var overscrollTop0 = (y0 - _initialMotionY) * DragRate; _isBeingDragged = false; if (overscrollTop0 > _totalDragDistance) { SetRefreshing(true, true /* notify */); } else { // cancel refresh _refreshing = false; _progress.SetStartEndTrim(0f, 0f); IAnimationListener listener = null; if (!_scale) { listener = new CustomCancelListener(this); } AnimateOffsetToStartPosition(_currentTargetOffsetTop, listener); _progress.ShowArrow(false); } _activePointerId = InvalidPointer; return(false); } } return(true); }