Loading core/java/android/widget/EdgeEffect.java +69 −21 Original line number Diff line number Diff line Loading @@ -25,8 +25,12 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.BlendMode; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.graphics.RenderEffect; import android.graphics.RenderNode; import android.os.Build; import android.util.AttributeSet; import android.view.animation.AnimationUtils; Loading Loading @@ -149,6 +153,8 @@ public class EdgeEffect { private float mDisplacement = 0.5f; private float mTargetDisplacement = 0.5f; private @EdgeEffectType int mEdgeEffectType = TYPE_GLOW; private Matrix mTmpMatrix = null; private float[] mTmpPoints = null; /** * Construct a new EdgeEffect with a theme appropriate for the provided context. Loading Loading @@ -250,12 +256,19 @@ public class EdgeEffect { public void onPull(float deltaDistance, float displacement) { final long now = AnimationUtils.currentAnimationTimeMillis(); mTargetDisplacement = displacement; if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration) { if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration && mEdgeEffectType == TYPE_GLOW) { return; } if (mState != STATE_PULL) { if (mEdgeEffectType == TYPE_STRETCH) { // Restore the mPullDistance to the fraction it is currently showing -- we want // to "catch" the current stretch value. mPullDistance = mDistance; } else { mGlowScaleY = Math.max(PULL_GLOW_BEGIN, mGlowScaleY); } } mState = STATE_PULL; mStartTime = now; Loading Loading @@ -313,6 +326,15 @@ public class EdgeEffect { public float onPullDistance(float deltaDistance, float displacement) { float finalDistance = Math.max(0f, deltaDistance + mDistance); float delta = finalDistance - mDistance; if (delta == 0f && mDistance == 0f) { return 0f; // No pull, don't do anything. } if (mState != STATE_PULL && mState != STATE_PULL_DECAY && mEdgeEffectType == TYPE_GLOW) { // Catch the edge glow in the middle of an animation. mPullDistance = mDistance; mState = STATE_PULL; } onPull(delta, displacement); return delta; } Loading Loading @@ -466,15 +488,16 @@ public class EdgeEffect { * Draw into the provided canvas. Assumes that the canvas has been rotated * accordingly and the size has been set. The effect will be drawn the full * width of X=0 to X=width, beginning from Y=0 and extending to some factor < * 1.f of height. * 1.f of height. The {@link #TYPE_STRETCH} effect will only be visible on a * hardware canvas, e.g. {@link RenderNode#beginRecording()}. * * @param canvas Canvas to draw into * @return true if drawing should continue beyond this frame to continue the * animation */ public boolean draw(Canvas canvas) { if (mEdgeEffectType == TYPE_GLOW) { update(); final int count = canvas.save(); final float centerX = mBounds.centerX(); Loading @@ -490,9 +513,34 @@ public class EdgeEffect { mPaint.setAlpha((int) (0xff * mGlowAlpha)); canvas.drawCircle(centerX, centerY, mRadius, mPaint); canvas.restoreToCount(count); } else if (canvas instanceof RecordingCanvas) { if (mState != STATE_PULL) { update(); } RecordingCanvas recordingCanvas = (RecordingCanvas) canvas; if (mTmpMatrix == null) { mTmpMatrix = new Matrix(); mTmpPoints = new float[4]; } //noinspection deprecation recordingCanvas.getMatrix(mTmpMatrix); mTmpPoints[0] = mBounds.width() * mDisplacement; mTmpPoints[1] = mDistance * mBounds.height(); mTmpPoints[2] = mTmpPoints[0]; mTmpPoints[3] = 0; mTmpMatrix.mapPoints(mTmpPoints); float x = mTmpPoints[0] - mTmpPoints[2]; float y = mTmpPoints[1] - mTmpPoints[3]; RenderNode renderNode = recordingCanvas.mNode; // TODO: use stretchy RenderEffect and use internal API when it is ready // TODO: wrap existing RenderEffect renderNode.setRenderEffect(RenderEffect.createOffsetEffect(x, y)); } boolean oneLastFrame = false; if (mState == STATE_RECEDE && mGlowScaleY == 0) { if (mState == STATE_RECEDE && mDistance == 0) { mState = STATE_IDLE; oneLastFrame = true; } Loading Loading
core/java/android/widget/EdgeEffect.java +69 −21 Original line number Diff line number Diff line Loading @@ -25,8 +25,12 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.BlendMode; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.graphics.RenderEffect; import android.graphics.RenderNode; import android.os.Build; import android.util.AttributeSet; import android.view.animation.AnimationUtils; Loading Loading @@ -149,6 +153,8 @@ public class EdgeEffect { private float mDisplacement = 0.5f; private float mTargetDisplacement = 0.5f; private @EdgeEffectType int mEdgeEffectType = TYPE_GLOW; private Matrix mTmpMatrix = null; private float[] mTmpPoints = null; /** * Construct a new EdgeEffect with a theme appropriate for the provided context. Loading Loading @@ -250,12 +256,19 @@ public class EdgeEffect { public void onPull(float deltaDistance, float displacement) { final long now = AnimationUtils.currentAnimationTimeMillis(); mTargetDisplacement = displacement; if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration) { if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration && mEdgeEffectType == TYPE_GLOW) { return; } if (mState != STATE_PULL) { if (mEdgeEffectType == TYPE_STRETCH) { // Restore the mPullDistance to the fraction it is currently showing -- we want // to "catch" the current stretch value. mPullDistance = mDistance; } else { mGlowScaleY = Math.max(PULL_GLOW_BEGIN, mGlowScaleY); } } mState = STATE_PULL; mStartTime = now; Loading Loading @@ -313,6 +326,15 @@ public class EdgeEffect { public float onPullDistance(float deltaDistance, float displacement) { float finalDistance = Math.max(0f, deltaDistance + mDistance); float delta = finalDistance - mDistance; if (delta == 0f && mDistance == 0f) { return 0f; // No pull, don't do anything. } if (mState != STATE_PULL && mState != STATE_PULL_DECAY && mEdgeEffectType == TYPE_GLOW) { // Catch the edge glow in the middle of an animation. mPullDistance = mDistance; mState = STATE_PULL; } onPull(delta, displacement); return delta; } Loading Loading @@ -466,15 +488,16 @@ public class EdgeEffect { * Draw into the provided canvas. Assumes that the canvas has been rotated * accordingly and the size has been set. The effect will be drawn the full * width of X=0 to X=width, beginning from Y=0 and extending to some factor < * 1.f of height. * 1.f of height. The {@link #TYPE_STRETCH} effect will only be visible on a * hardware canvas, e.g. {@link RenderNode#beginRecording()}. * * @param canvas Canvas to draw into * @return true if drawing should continue beyond this frame to continue the * animation */ public boolean draw(Canvas canvas) { if (mEdgeEffectType == TYPE_GLOW) { update(); final int count = canvas.save(); final float centerX = mBounds.centerX(); Loading @@ -490,9 +513,34 @@ public class EdgeEffect { mPaint.setAlpha((int) (0xff * mGlowAlpha)); canvas.drawCircle(centerX, centerY, mRadius, mPaint); canvas.restoreToCount(count); } else if (canvas instanceof RecordingCanvas) { if (mState != STATE_PULL) { update(); } RecordingCanvas recordingCanvas = (RecordingCanvas) canvas; if (mTmpMatrix == null) { mTmpMatrix = new Matrix(); mTmpPoints = new float[4]; } //noinspection deprecation recordingCanvas.getMatrix(mTmpMatrix); mTmpPoints[0] = mBounds.width() * mDisplacement; mTmpPoints[1] = mDistance * mBounds.height(); mTmpPoints[2] = mTmpPoints[0]; mTmpPoints[3] = 0; mTmpMatrix.mapPoints(mTmpPoints); float x = mTmpPoints[0] - mTmpPoints[2]; float y = mTmpPoints[1] - mTmpPoints[3]; RenderNode renderNode = recordingCanvas.mNode; // TODO: use stretchy RenderEffect and use internal API when it is ready // TODO: wrap existing RenderEffect renderNode.setRenderEffect(RenderEffect.createOffsetEffect(x, y)); } boolean oneLastFrame = false; if (mState == STATE_RECEDE && mGlowScaleY == 0) { if (mState == STATE_RECEDE && mDistance == 0) { mState = STATE_IDLE; oneLastFrame = true; } Loading