@Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (mPositionDataList == null || mPositionDataList.isEmpty()) { return; } // 计算锚点位置 int currentPosition = Math.min(mPositionDataList.size() - 1, position); int nextPosition = Math.min(mPositionDataList.size() - 1, position + 1); PositionData current = mPositionDataList.get(currentPosition); PositionData next = mPositionDataList.get(nextPosition); mRect.left = current.mContentLeft - mHorizontalPadding + (next.mContentLeft - current.mContentLeft) * mEndInterpolator.getInterpolation(positionOffset); mRect.top = current.mContentTop - mVerticalPadding; mRect.right = current.mContentRight + mHorizontalPadding + (next.mContentRight - current.mContentRight) * mStartInterpolator.getInterpolation(positionOffset); mRect.bottom = current.mContentBottom + mVerticalPadding; if (!mRoundRadiusSet) { mRoundRadius = mRect.height() / 2; } invalidate(); }
private void updateWave() { float progress = Math.min(1f, (float) (SystemClock.uptimeMillis() - mStartTime) / mRippleAnimDuration); if (mState != STATE_RELEASE) { setRippleEffect( mRipplePoint.x, mRipplePoint.y, mMaxRippleRadius * mInInterpolator.getInterpolation(progress)); if (progress == 1f) { mStartTime = SystemClock.uptimeMillis(); if (mState == STATE_PRESS) setRippleState(STATE_HOVER); else { setRippleEffect(mRipplePoint.x, mRipplePoint.y, 0); setRippleState(STATE_RELEASE); } } } else { setRippleEffect( mRipplePoint.x, mRipplePoint.y, mMaxRippleRadius * mOutInterpolator.getInterpolation(progress)); if (progress == 1f) setRippleState(STATE_OUT); } if (isRunning()) scheduleSelf(mUpdater, SystemClock.uptimeMillis() + ViewUtil.FRAME_DURATION); invalidateSelf(); }
@Override public float getInterpolation(float t) { if (t < 0.5) { return 0.5f * BounceEaseIn.getInterpolation(t * 2.0f); } else { return 0.5f * BounceEaseOut.getInterpolation(t * 2.0f - 1.0f) + 0.5f; } }
@Override public void draw(Canvas canvas) { if (!mRunning) { if (mVisible) canvas.drawCircle(mX, mY, mRadius, mPaint); } else { float radius = mVisible ? mInInterpolator.getInterpolation(mAnimProgress) * mRadius : (1f - mOutInterpolator.getInterpolation(mAnimProgress)) * mRadius; canvas.drawCircle(mX, mY, radius, mPaint); } }
public boolean calculate(final long currentTimeMillis) { if (mStartTime == NO_ANIMATION) return false; if (mStartTime == ANIMATION_START) { mStartTime = currentTimeMillis; } final int elapse = (int) (currentTimeMillis - mStartTime); final float x = Utils.clamp((float) elapse / mDuration, 0f, 1f); final Interpolator i = mInterpolator; onCalculate(i != null ? i.getInterpolation(x) : x); if (elapse >= mDuration) { mStartTime = NO_ANIMATION; } return mStartTime != NO_ANIMATION; }
public boolean calculate(long paramLong) { if (this.mStartTime == -2L) ; do { return false; if (this.mStartTime == -1L) this.mStartTime = paramLong; int i = (int) (paramLong - this.mStartTime); float f = Utils.clamp(i / this.mDuration, 0.0F, 1.0F); Interpolator localInterpolator = this.mInterpolator; if (localInterpolator != null) f = localInterpolator.getInterpolation(f); onCalculate(f); if (i < this.mDuration) continue; this.mStartTime = -2L; } while (this.mStartTime == -2L); return true; }
public void run() { /** * Only set mStartTime if this is the first time we're starting, else actually calculate the Y * delta */ if (mStartTime == -1) { mStartTime = System.currentTimeMillis(); } else { /** * We do do all calculations in long to reduce software float calculations. We use 1000 as * it gives us good accuracy and small rounding errors */ long normalizedTime = (1000 * (System.currentTimeMillis() - mStartTime)) / ANIMATION_DURATION_MS; normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0); final int deltaY = Math.round( (mScrollFromY - mScrollToY) * mInterpolator.getInterpolation(normalizedTime / 1000f)); mCurrentY = mScrollFromY - deltaY; setHeaderScroll(mCurrentY); } // If we're not at the target Y, keep going... if (mContinueRunning && mScrollToY != mCurrentY) { mHandler.postDelayed(this, ANIMATION_FPS); } }
@Override public void run() { /** * Only set mStartTime if this is the first time we're starting, else actually calculate the Y * delta */ if (mStartTime == -1) { mStartTime = System.currentTimeMillis(); } else { /** * We do do all calculations in long to reduce software float calculations. We use 1000 as * it gives us good accuracy and small rounding errors */ long normalizedTime = (1000 * (System.currentTimeMillis() - mStartTime)) / mDuration; normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0); final int deltaY = Math.round( (mScrollFromY - mScrollToY) * mInterpolator.getInterpolation(normalizedTime / 1000f)); mCurrentY = mScrollFromY - deltaY; setHeaderScroll(mCurrentY); } // If we're not at the target Y, keep going... if (mContinueRunning && mScrollToY != mCurrentY) { // if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { // SDK16.postOnAnimation(PullToRefreshBase.this, this); // } else { postDelayed(this, ANIMATION_DELAY); // } } }
@Override public void run() { /** * Only set mStartTime if this is the first time we're starting, else actually calculate the Y * delta */ if (mStartTime == -1) { mStartTime = System.currentTimeMillis(); } else { /** * We do do all calculations in long to reduce software float calculations. We use 1000 as * it gives us good accuracy and small rounding errors */ long normalizedTime = (1000 * (System.currentTimeMillis() - mStartTime)) / mDuration; normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0); final int deltaY = Math.round( (mScrollFromY - mScrollToY) * mInterpolator.getInterpolation(normalizedTime / 1000f)); mCurrentY = mScrollFromY - deltaY; setHeaderScroll(mCurrentY); } // If we're not at the target Y, keep going... if (mContinueRunning && mScrollToY != mCurrentY) { ViewCompat.postOnAnimation(PullToRefreshBase.this, this); } else { if (null != mListener) { mListener.onSmoothScrollFinished(); } } }
private void updateSwapTargetTranslation( RecyclerView.ViewHolder draggingItem, RecyclerView.ViewHolder swapTargetItem, float translationPhase) { final View swapItemView = swapTargetItem.itemView; final int pos1 = draggingItem.getLayoutPosition(); final int pos2 = swapTargetItem.getLayoutPosition(); final Rect m1 = mDraggingItemMargins; final Rect d1 = mDraggingItemDecorationOffsets; final int h1 = mDraggingItemHeight + m1.top + m1.bottom + d1.top + d1.bottom; if (mSwapTargetTranslationInterpolator != null) { translationPhase = mSwapTargetTranslationInterpolator.getInterpolation(translationPhase); } if (pos1 > pos2) { // dragging item moving to upward ViewCompat.setTranslationY(swapItemView, translationPhase * h1); } else { // dragging item moving to downward ViewCompat.setTranslationY(swapItemView, (translationPhase - 1.0f) * h1); } }
private void transform(View page, float position) { float interpolatorPosition; float translationX; int pageWidth = page.getWidth(); if (mOutset <= 0) { mOutset = (int) (mOutsetFraction * page.getWidth()); } if (position < 0) { interpolatorPosition = mInterpolator.getInterpolation(Math.abs(position)); translationX = -mEvaluator.evaluate(interpolatorPosition, 0, (pageWidth - mOutset)); } else { interpolatorPosition = mInterpolator.getInterpolation(position); translationX = mEvaluator.evaluate(interpolatorPosition, 0, (pageWidth - mOutset)); } translationX += -page.getWidth() * position; page.setTranslationX(translationX); }
private void updateQuery() { long curTime = SystemClock.uptimeMillis(); mAnimTime = (float) (curTime - mLastProgressStateTime) / mTravelDuration; boolean requestUpdate = mRunState == RUN_STATE_STOPPING || mProgressPercent == 0 || mAnimTime < 1f; if (mAnimTime > 1f) { mLastProgressStateTime = Math.round(curTime - (mAnimTime - 1f) * mTravelDuration); mAnimTime -= 1f; } if (requestUpdate && mRunState != RUN_STATE_STOPPING) { Rect bounds = getBounds(); int width = bounds.width(); float maxWidth = mMaxLineWidth == 0 ? width * mMaxLineWidthPercent : mMaxLineWidth; float minWidth = mMinLineWidth == 0 ? width * mMinLineWidthPercent : mMinLineWidth; mLineWidth = mTransformInterpolator.getInterpolation(mAnimTime) * (minWidth - maxWidth) + maxWidth; if (mReverse) mLineWidth = -mLineWidth; mStartLine = mReverse ? mTransformInterpolator.getInterpolation(mAnimTime) * (width + minWidth) : ((1f - mTransformInterpolator.getInterpolation(mAnimTime)) * (width + minWidth) - minWidth); } if (mRunState == RUN_STATE_STARTING) { if (curTime - mLastRunStateTime > mInAnimationDuration) mRunState = RUN_STATE_RUNNING; } else if (mRunState == RUN_STATE_STOPPING) { if (curTime - mLastRunStateTime > mOutAnimationDuration) { stop(false); return; } } if (isRunning()) { if (requestUpdate) scheduleSelf(mUpdater, SystemClock.uptimeMillis() + ViewUtil.FRAME_DURATION); else if (mRunState == RUN_STATE_RUNNING) mRunState = RUN_STATE_STARTED; } invalidateSelf(); }
private void drawCircle(Canvas var1, float var2, float var3, int var4, float var5) { this.mPaint.setColor(var4); var1.save(); var1.translate(var2, var3); var3 = INTERPOLATOR.getInterpolation(var5); var1.scale(var3, var3); var1.drawCircle(0.0F, 0.0F, var2, this.mPaint); var1.restore(); }
/** * Draws a circle centered in the view. * * @param canvas the canvas to draw on * @param cx the center x coordinate * @param cy the center y coordinate * @param color the color to draw * @param pct the percentage of the view that the circle should cover */ private void drawCircle(Canvas canvas, float cx, float cy, int color, float pct) { mPaint.setColor(color); canvas.save(); canvas.translate(cx, cy); float radiusScale = INTERPOLATOR.getInterpolation(pct); canvas.scale(radiusScale, radiusScale); canvas.drawCircle(0, 0, cx, mPaint); canvas.restore(); }
/** * Computes the current zoom level, returning true if the zoom is still active and false if the * zoom has finished. * * @see android.widget.Scroller#computeScrollOffset() */ public boolean computeZoom() { if (mFinished) { return false; } long tRTC = SystemClock.elapsedRealtime() - mStartRTC; if (tRTC >= mAnimationDurationMillis) { mFinished = true; mCurrentZoom = mEndZoom; applyZoomToCurrentRect(1f); return false; } float t = tRTC * 1f / mAnimationDurationMillis; mCurrentZoom = mEndZoom * mInterpolator.getInterpolation(t); applyZoomToCurrentRect(mInterpolator.getInterpolation(t)); return true; }
private void drawCircle( Canvas paramCanvas, float paramFloat1, float paramFloat2, int paramInt, float paramFloat3) { this.mPaint.setColor(paramInt); paramCanvas.save(); paramCanvas.translate(paramFloat1, paramFloat2); paramFloat2 = INTERPOLATOR.getInterpolation(paramFloat3); paramCanvas.scale(paramFloat2, paramFloat2); paramCanvas.drawCircle(0.0F, 0.0F, paramFloat1, this.mPaint); paramCanvas.restore(); }
public static void getInterpolatorPoint( Point startPoint, Point endPoint, Point outPoint, float t) { if (outPoint == null) { return; } t = INTERPOLATOR.getInterpolation(t); t = Math.min(t, 1); t = Math.max(t, 0); outPoint.x = (int) (startPoint.x + (endPoint.x - startPoint.x) * t); outPoint.y = (int) (startPoint.y + (endPoint.y - startPoint.y) * t); }
private void update() { float f; float f2; f = Math.min((float)(AnimationUtils.currentAnimationTimeMillis() - mStartTime) / mDuration, 1.0F); f2 = mInterpolator.getInterpolation(f); mEdgeAlpha = mEdgeAlphaStart + (mEdgeAlphaFinish - mEdgeAlphaStart) * f2; mEdgeScaleY = mEdgeScaleYStart + (mEdgeScaleYFinish - mEdgeScaleYStart) * f2; mGlowAlpha = mGlowAlphaStart + (mGlowAlphaFinish - mGlowAlphaStart) * f2; mGlowScaleY = mGlowScaleYStart + (mGlowScaleYFinish - mGlowScaleYStart) * f2; if (f < 0.999F) goto _L2; else goto _L1
/** * Call this when you want to know the new location. If it returns true, the animation is not yet * finished. */ public boolean computeScrollOffset() { if (mFinished) { return false; } int timePassed = (int) (AnimationUtils.currentAnimationTimeMillis() - mStartTime); if (timePassed < mDuration) { switch (mMode) { case SCROLL_MODE: final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal); mCurrX = mStartX + Math.round(x * mDeltaX); mCurrY = mStartY + Math.round(x * mDeltaY); break; case FLING_MODE: final float t = (float) timePassed / mDuration; final int index = (int) (NB_SAMPLES * t); float distanceCoef = 1.f; float velocityCoef = 0.f; if (index < NB_SAMPLES) { final float t_inf = (float) index / NB_SAMPLES; final float t_sup = (float) (index + 1) / NB_SAMPLES; final float d_inf = SPLINE_POSITION[index]; final float d_sup = SPLINE_POSITION[index + 1]; velocityCoef = (d_sup - d_inf) / (t_sup - t_inf); distanceCoef = d_inf + (t - t_inf) * velocityCoef; } mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f; mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX)); // Pin to mMinX <= mCurrX <= mMaxX mCurrX = Math.min(mCurrX, mMaxX); mCurrX = Math.max(mCurrX, mMinX); mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY)); // Pin to mMinY <= mCurrY <= mMaxY mCurrY = Math.min(mCurrY, mMaxY); mCurrY = Math.max(mCurrY, mMinY); if (mCurrX == mFinalX && mCurrY == mFinalY) { mFinished = true; } break; } } else { mCurrX = mFinalX; mCurrY = mFinalY; mFinished = true; } return true; }
@Override public float getInterpolation(float input) { Interpolator interpolator = null; final float targetDuration = totalDuration * input; float durationSum = 0; float from = 0f; float to = 0f; float modifiedInput = 0f; for (int i = 0; i < interpolators.length; ++i) { float oldDurationSum = durationSum; float duration = durations[i]; durationSum += duration; to = targets[i]; if (targetDuration <= durationSum) { interpolator = interpolators[i]; modifiedInput = (targetDuration - oldDurationSum) / duration; break; } from = to; } return from + (to - from) * interpolator.getInterpolation(modifiedInput); }
private void animationSleep(int j, Interpolator interpolator, float delta) throws InterruptedException { int interpolation = (int) (interpolator.getInterpolation(j / delta) * 10000000); int milliseconds = 0; if (interpolation >= MAX_SLEEP_NANOS) { milliseconds = interpolation / NANO_SECS; interpolation = interpolation % NANO_SECS; } try { Thread.sleep(milliseconds, interpolation); } catch (IllegalArgumentException ignore) { } }
void animateValue(float fraction) { fraction = mInterpolator.getInterpolation(fraction); mCurrentFraction = fraction; int numValues = mValues.length; for (PropertyValuesHolder mValue : mValues) { mValue.calculateValue(fraction); } if (mUpdateListeners != null) { int numListeners = mUpdateListeners.size(); for (AnimatorUpdateListener mUpdateListener : mUpdateListeners) { mUpdateListener.onAnimationUpdate(this); } } }
/** * This method is called with the elapsed fraction of the animation during every animation frame. * This function turns the elapsed fraction into an interpolated fraction and then into an * animated value (from the evaluator. The function is called mostly during animation updates, but * it is also called when the <code>end()</code> function is called, to set the final value on the * property. * * <p>Overrides of this method must call the superclass to perform the calculation of the animated * value. * * @param fraction The elapsed fraction of the animation. */ void animateValue(float fraction) { fraction = mInterpolator.getInterpolation(fraction); mCurrentFraction = fraction; int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { mValues[i].calculateValue(fraction); } if (mUpdateListeners != null) { int numListeners = mUpdateListeners.size(); for (int i = 0; i < numListeners; ++i) { mUpdateListeners.get(i).onAnimationUpdate(this); } } }
@Override public void run() { long now = AnimationUtils.currentAnimationTimeMillis(); long duration = now - mStartTime; if (duration >= ANIMATION_DURATION) { mAlpha = 0.0f; invalidate(); stop(); return; } else { mAlpha = mInterpolator.getInterpolation(1 - duration / (float) ANIMATION_DURATION); invalidate(); } postDelayed(mUpdater, FRAME_DURATION); }
@Override public void run() { long currentTime = SystemClock.uptimeMillis(); long diff = currentTime - mStartTime; if (diff < mDuration) { float interpolation = mInterpolator.getInterpolation((float) diff / (float) mDuration); scheduleSelf(mUpdater, currentTime + FRAME_DURATION); updateAnimation(interpolation); } else { unscheduleSelf(mUpdater); mRunning = false; updateAnimation(1f); } }
/** * Gets the animated value, given the elapsed fraction of the animation (interpolated by the * animation's interpolator) and the evaluator used to calculate in-between values. This function * maps the input fraction to the appropriate keyframe interval and a fraction between them and * returns the interpolated value. Note that the input fraction may fall outside the [0-1] bounds, * if the animation's interpolator made that happen (e.g., a spring interpolation that might send * the fraction past 1.0). We handle this situation by just using the two keyframes at the * appropriate end when the value is outside those bounds. * * @param fraction The elapsed fraction of the animation * @return The animated value. */ public Object getValue(float fraction) { // Special-case optimization for the common case of only two keyframes if (mNumKeyframes == 2) { if (mInterpolator != null) { fraction = mInterpolator.getInterpolation(fraction); } return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(), mLastKeyframe.getValue()); } if (fraction <= 0f) { final Keyframe nextKeyframe = mKeyframes.get(1); final /*Time*/ Interpolator interpolator = nextKeyframe.getInterpolator(); if (interpolator != null) { fraction = interpolator.getInterpolation(fraction); } final float prevFraction = mFirstKeyframe.getFraction(); float intervalFraction = (fraction - prevFraction) / (nextKeyframe.getFraction() - prevFraction); return mEvaluator.evaluate( intervalFraction, mFirstKeyframe.getValue(), nextKeyframe.getValue()); } else if (fraction >= 1f) { final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2); final /*Time*/ Interpolator interpolator = mLastKeyframe.getInterpolator(); if (interpolator != null) { fraction = interpolator.getInterpolation(fraction); } final float prevFraction = prevKeyframe.getFraction(); float intervalFraction = (fraction - prevFraction) / (mLastKeyframe.getFraction() - prevFraction); return mEvaluator.evaluate( intervalFraction, prevKeyframe.getValue(), mLastKeyframe.getValue()); } Keyframe prevKeyframe = mFirstKeyframe; for (int i = 1; i < mNumKeyframes; ++i) { Keyframe nextKeyframe = mKeyframes.get(i); if (fraction < nextKeyframe.getFraction()) { final /*Time*/ Interpolator interpolator = nextKeyframe.getInterpolator(); if (interpolator != null) { fraction = interpolator.getInterpolation(fraction); } final float prevFraction = prevKeyframe.getFraction(); float intervalFraction = (fraction - prevFraction) / (nextKeyframe.getFraction() - prevFraction); return mEvaluator.evaluate( intervalFraction, prevKeyframe.getValue(), nextKeyframe.getValue()); } prevKeyframe = nextKeyframe; } // shouldn't reach here return mLastKeyframe.getValue(); }
@Override public void computeRender(float renderProgress) { if (mRiverPath == null) { return; } if (mRiverMeasure == null) { mRiverMeasure = new PathMeasure(mRiverPath, false); } float fishProgress = FISH_INTERPOLATOR.getInterpolation(renderProgress); mRiverMeasure.getPosTan(mRiverMeasure.getLength() * fishProgress, mFishHeadPos, null); mFishRotateDegrees = calculateRotateDegrees(fishProgress); }
@Override public final void run() { if (!mStarted) return; final long timeElapsed = AnimationUtils.currentAnimationTimeMillis() - mStartTime; mAnimationValue = mInterpolator.getInterpolation(timeElapsed / (float) mDuration); onAnimationUpdate(); if (timeElapsed < mDuration) { Compat.postOnAnimation(mView, this); } else { if (++mRunCount < mRepeatCount || mRepeatCount == INFINITE) { restart(); } } }
private void update() { long curTime = SystemClock.uptimeMillis(); float progress = Math.min(1f, (float) (curTime - mStartTime) / mAnimDuration); float value = mInterpolator.getInterpolation(progress); mThumbPosition = mChecked ? (mStartPosition * (1 - value) + value) : (mStartPosition * (1 - value)); if (progress == 1f) stopAnimation(); if (mRunning) { if (getHandler() != null) getHandler().postAtTime(mUpdater, SystemClock.uptimeMillis() + ViewUtil.FRAME_DURATION); else stopAnimation(); } invalidate(); }
/** * Call this when you want to know the new location. If it returns true, the animation is not yet * finished. */ public boolean computeScrollOffset() { if (isFinished()) { return false; } switch (mMode) { case SCROLL_MODE: long time = AnimationUtils.currentAnimationTimeMillis(); // Any scroller can be used for time, since they were started // together in scroll mode. We use X here. final long elapsedTime = time - mScrollerX.mStartTime; final int duration = mScrollerX.mDuration; if (elapsedTime < duration) { final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration); mScrollerX.updateScroll(q); mScrollerY.updateScroll(q); } else { abortAnimation(); } break; case FLING_MODE: if (!mScrollerX.mFinished) { if (!mScrollerX.update()) { if (!mScrollerX.continueWhenFinished()) { mScrollerX.finish(); } } } if (!mScrollerY.mFinished) { if (!mScrollerY.update()) { if (!mScrollerY.continueWhenFinished()) { mScrollerY.finish(); } } } break; } return true; }