Loading core/api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -53591,16 +53591,19 @@ package android.widget { public class EdgeEffect { ctor public EdgeEffect(android.content.Context); ctor public EdgeEffect(@NonNull android.content.Context, @Nullable android.util.AttributeSet); method public boolean draw(android.graphics.Canvas); method public void finish(); method @Nullable public android.graphics.BlendMode getBlendMode(); method @ColorInt public int getColor(); method public float getDistance(); method public int getMaxHeight(); method public int getType(); method public boolean isFinished(); method public void onAbsorb(int); method public void onPull(float); method public void onPull(float, float); method public float onPullDistance(float, float); method public void onRelease(); method public void setBlendMode(@Nullable android.graphics.BlendMode); method public void setColor(@ColorInt int); core/java/android/widget/EdgeEffect.java +93 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.widget; import android.annotation.ColorInt; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; Loading @@ -27,6 +28,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.os.Build; import android.util.AttributeSet; import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; Loading Loading @@ -111,11 +113,14 @@ public class EdgeEffect { private float mGlowAlpha; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mGlowScaleY; private float mDistance; private float mGlowAlphaStart; private float mGlowAlphaFinish; private float mGlowScaleYStart; private float mGlowScaleYFinish; private float mDistanceStart; private float mDistanceFinish; private long mStartTime; private float mDuration; Loading Loading @@ -150,9 +155,18 @@ public class EdgeEffect { * @param context Context used to provide theming and resource information for the EdgeEffect */ public EdgeEffect(Context context) { this(context, null); } /** * Construct a new EdgeEffect with a theme appropriate for the provided context. * @param context Context used to provide theming and resource information for the EdgeEffect * @param attrs The attributes of the XML tag that is inflating the view */ public EdgeEffect(@NonNull Context context, @Nullable AttributeSet attrs) { mPaint.setAntiAlias(true); final TypedArray a = context.obtainStyledAttributes( com.android.internal.R.styleable.EdgeEffect); attrs, com.android.internal.R.styleable.EdgeEffect); final int themeColor = a.getColor( com.android.internal.R.styleable.EdgeEffect_colorEdgeEffect, 0xff666666); mEdgeEffectType = a.getInt( Loading Loading @@ -248,6 +262,7 @@ public class EdgeEffect { mDuration = PULL_TIME; mPullDistance += deltaDistance; mDistanceStart = mDistanceFinish = mDistance = Math.max(0f, mPullDistance); final float absdd = Math.abs(deltaDistance); mGlowAlpha = mGlowAlphaStart = Math.min(MAX_ALPHA, Loading @@ -266,6 +281,56 @@ public class EdgeEffect { mGlowScaleYFinish = mGlowScaleY; } /** * A view should call this when content is pulled away from an edge by the user. * This will update the state of the current visual effect and its associated animation. * The host view should always {@link android.view.View#invalidate()} after this * and draw the results accordingly. This works similarly to {@link #onPull(float, float)}, * but returns the amount of <code>deltaDistance</code> that has been consumed. If the * {@link #getDistance()} is currently 0 and <code>deltaDistance</code> is negative, this * function will return 0 and the drawn value will remain unchanged. * * This method can be used to reverse the effect from a pull or absorb and partially consume * some of a motion: * * <pre class="prettyprint"> * if (deltaY < 0) { * float consumed = edgeEffect.onPullDistance(deltaY / getHeight(), x / getWidth()); * deltaY -= consumed * getHeight(); * if (edgeEffect.getDistance() == 0f) edgeEffect.onRelease(); * } * </pre> * * @param deltaDistance Change in distance since the last call. Values may be 0 (no change) to * 1.f (full length of the view) or negative values to express change * back toward the edge reached to initiate the effect. * @param displacement The displacement from the starting side of the effect of the point * initiating the pull. In the case of touch this is the finger position. * Values may be from 0-1. * @return The amount of <code>deltaDistance</code> that was consumed, a number between * 0 and <code>deltaDistance</code>. */ public float onPullDistance(float deltaDistance, float displacement) { float finalDistance = Math.max(0f, deltaDistance + mDistance); float delta = finalDistance - mDistance; onPull(delta, displacement); return delta; } /** * Returns the pull distance needed to be released to remove the showing effect. * It is determined by the {@link #onPull(float, float)} <code>deltaDistance</code> and * any animating values, including from {@link #onAbsorb(int)} and {@link #onRelease()}. * * This can be used in conjunction with {@link #onPullDistance(float, float)} to * release the currently showing effect. * * @return The pull distance that must be released to remove the showing effect. */ public float getDistance() { return mDistance; } /** * Call when the object is released after being pulled. * This will begin the "decay" phase of the effect. After calling this method Loading @@ -282,9 +347,11 @@ public class EdgeEffect { mState = STATE_RECEDE; mGlowAlphaStart = mGlowAlpha; mGlowScaleYStart = mGlowScaleY; mDistanceStart = mDistance; mGlowAlphaFinish = 0.f; mGlowScaleYFinish = 0.f; mDistanceFinish = 0.f; mStartTime = AnimationUtils.currentAnimationTimeMillis(); mDuration = RECEDE_TIME; Loading @@ -311,7 +378,7 @@ public class EdgeEffect { // nearly invisible. mGlowAlphaStart = GLOW_ALPHA_START; mGlowScaleYStart = Math.max(mGlowScaleY, 0.f); mDistanceStart = mDistance; // Growth for the size of the glow should be quadratic to properly // respond Loading @@ -322,6 +389,9 @@ public class EdgeEffect { mGlowAlphaFinish = Math.max( mGlowAlphaStart, Math.min(velocity * VELOCITY_GLOW_FACTOR * .00001f, MAX_ALPHA)); mTargetDisplacement = 0.5f; // Use glow values to estimate the absorption for stretch distance. mDistanceFinish = calculateDistanceFromGlowValues(mGlowScaleYFinish, mGlowAlphaFinish); } /** Loading Loading @@ -447,6 +517,7 @@ public class EdgeEffect { mGlowAlpha = mGlowAlphaStart + (mGlowAlphaFinish - mGlowAlphaStart) * interp; mGlowScaleY = mGlowScaleYStart + (mGlowScaleYFinish - mGlowScaleYStart) * interp; mDistance = mDistanceStart + (mDistanceFinish - mDistanceStart) * interp; mDisplacement = (mDisplacement + mTargetDisplacement) / 2; if (t >= 1.f - EPSILON) { Loading @@ -458,10 +529,12 @@ public class EdgeEffect { mGlowAlphaStart = mGlowAlpha; mGlowScaleYStart = mGlowScaleY; mDistanceStart = mDistance; // After absorb, the glow should fade to nothing. mGlowAlphaFinish = 0.f; mGlowScaleYFinish = 0.f; mDistanceFinish = 0.f; break; case STATE_PULL: mState = STATE_PULL_DECAY; Loading @@ -470,10 +543,12 @@ public class EdgeEffect { mGlowAlphaStart = mGlowAlpha; mGlowScaleYStart = mGlowScaleY; mDistanceStart = mDistance; // After pull, the glow should fade to nothing. mGlowAlphaFinish = 0.f; mGlowScaleYFinish = 0.f; mDistanceFinish = 0.f; break; case STATE_PULL_DECAY: mState = STATE_RECEDE; Loading @@ -484,4 +559,20 @@ public class EdgeEffect { } } } /** * @return The estimated pull distance as calculated from mGlowScaleY. */ private float calculateDistanceFromGlowValues(float scale, float alpha) { if (scale >= 1f) { // It should asymptotically approach 1, but not reach there. // Here, we're just choosing a value that is large. return 1f; } if (scale > 0f) { float v = 1f / 0.7f / (mGlowScaleY - 1f); return v * v / mBounds.height(); } return alpha / PULL_DISTANCE_ALPHA_GLOW_FACTOR; } } Loading
core/api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -53591,16 +53591,19 @@ package android.widget { public class EdgeEffect { ctor public EdgeEffect(android.content.Context); ctor public EdgeEffect(@NonNull android.content.Context, @Nullable android.util.AttributeSet); method public boolean draw(android.graphics.Canvas); method public void finish(); method @Nullable public android.graphics.BlendMode getBlendMode(); method @ColorInt public int getColor(); method public float getDistance(); method public int getMaxHeight(); method public int getType(); method public boolean isFinished(); method public void onAbsorb(int); method public void onPull(float); method public void onPull(float, float); method public float onPullDistance(float, float); method public void onRelease(); method public void setBlendMode(@Nullable android.graphics.BlendMode); method public void setColor(@ColorInt int);
core/java/android/widget/EdgeEffect.java +93 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.widget; import android.annotation.ColorInt; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; Loading @@ -27,6 +28,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.os.Build; import android.util.AttributeSet; import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; Loading Loading @@ -111,11 +113,14 @@ public class EdgeEffect { private float mGlowAlpha; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mGlowScaleY; private float mDistance; private float mGlowAlphaStart; private float mGlowAlphaFinish; private float mGlowScaleYStart; private float mGlowScaleYFinish; private float mDistanceStart; private float mDistanceFinish; private long mStartTime; private float mDuration; Loading Loading @@ -150,9 +155,18 @@ public class EdgeEffect { * @param context Context used to provide theming and resource information for the EdgeEffect */ public EdgeEffect(Context context) { this(context, null); } /** * Construct a new EdgeEffect with a theme appropriate for the provided context. * @param context Context used to provide theming and resource information for the EdgeEffect * @param attrs The attributes of the XML tag that is inflating the view */ public EdgeEffect(@NonNull Context context, @Nullable AttributeSet attrs) { mPaint.setAntiAlias(true); final TypedArray a = context.obtainStyledAttributes( com.android.internal.R.styleable.EdgeEffect); attrs, com.android.internal.R.styleable.EdgeEffect); final int themeColor = a.getColor( com.android.internal.R.styleable.EdgeEffect_colorEdgeEffect, 0xff666666); mEdgeEffectType = a.getInt( Loading Loading @@ -248,6 +262,7 @@ public class EdgeEffect { mDuration = PULL_TIME; mPullDistance += deltaDistance; mDistanceStart = mDistanceFinish = mDistance = Math.max(0f, mPullDistance); final float absdd = Math.abs(deltaDistance); mGlowAlpha = mGlowAlphaStart = Math.min(MAX_ALPHA, Loading @@ -266,6 +281,56 @@ public class EdgeEffect { mGlowScaleYFinish = mGlowScaleY; } /** * A view should call this when content is pulled away from an edge by the user. * This will update the state of the current visual effect and its associated animation. * The host view should always {@link android.view.View#invalidate()} after this * and draw the results accordingly. This works similarly to {@link #onPull(float, float)}, * but returns the amount of <code>deltaDistance</code> that has been consumed. If the * {@link #getDistance()} is currently 0 and <code>deltaDistance</code> is negative, this * function will return 0 and the drawn value will remain unchanged. * * This method can be used to reverse the effect from a pull or absorb and partially consume * some of a motion: * * <pre class="prettyprint"> * if (deltaY < 0) { * float consumed = edgeEffect.onPullDistance(deltaY / getHeight(), x / getWidth()); * deltaY -= consumed * getHeight(); * if (edgeEffect.getDistance() == 0f) edgeEffect.onRelease(); * } * </pre> * * @param deltaDistance Change in distance since the last call. Values may be 0 (no change) to * 1.f (full length of the view) or negative values to express change * back toward the edge reached to initiate the effect. * @param displacement The displacement from the starting side of the effect of the point * initiating the pull. In the case of touch this is the finger position. * Values may be from 0-1. * @return The amount of <code>deltaDistance</code> that was consumed, a number between * 0 and <code>deltaDistance</code>. */ public float onPullDistance(float deltaDistance, float displacement) { float finalDistance = Math.max(0f, deltaDistance + mDistance); float delta = finalDistance - mDistance; onPull(delta, displacement); return delta; } /** * Returns the pull distance needed to be released to remove the showing effect. * It is determined by the {@link #onPull(float, float)} <code>deltaDistance</code> and * any animating values, including from {@link #onAbsorb(int)} and {@link #onRelease()}. * * This can be used in conjunction with {@link #onPullDistance(float, float)} to * release the currently showing effect. * * @return The pull distance that must be released to remove the showing effect. */ public float getDistance() { return mDistance; } /** * Call when the object is released after being pulled. * This will begin the "decay" phase of the effect. After calling this method Loading @@ -282,9 +347,11 @@ public class EdgeEffect { mState = STATE_RECEDE; mGlowAlphaStart = mGlowAlpha; mGlowScaleYStart = mGlowScaleY; mDistanceStart = mDistance; mGlowAlphaFinish = 0.f; mGlowScaleYFinish = 0.f; mDistanceFinish = 0.f; mStartTime = AnimationUtils.currentAnimationTimeMillis(); mDuration = RECEDE_TIME; Loading @@ -311,7 +378,7 @@ public class EdgeEffect { // nearly invisible. mGlowAlphaStart = GLOW_ALPHA_START; mGlowScaleYStart = Math.max(mGlowScaleY, 0.f); mDistanceStart = mDistance; // Growth for the size of the glow should be quadratic to properly // respond Loading @@ -322,6 +389,9 @@ public class EdgeEffect { mGlowAlphaFinish = Math.max( mGlowAlphaStart, Math.min(velocity * VELOCITY_GLOW_FACTOR * .00001f, MAX_ALPHA)); mTargetDisplacement = 0.5f; // Use glow values to estimate the absorption for stretch distance. mDistanceFinish = calculateDistanceFromGlowValues(mGlowScaleYFinish, mGlowAlphaFinish); } /** Loading Loading @@ -447,6 +517,7 @@ public class EdgeEffect { mGlowAlpha = mGlowAlphaStart + (mGlowAlphaFinish - mGlowAlphaStart) * interp; mGlowScaleY = mGlowScaleYStart + (mGlowScaleYFinish - mGlowScaleYStart) * interp; mDistance = mDistanceStart + (mDistanceFinish - mDistanceStart) * interp; mDisplacement = (mDisplacement + mTargetDisplacement) / 2; if (t >= 1.f - EPSILON) { Loading @@ -458,10 +529,12 @@ public class EdgeEffect { mGlowAlphaStart = mGlowAlpha; mGlowScaleYStart = mGlowScaleY; mDistanceStart = mDistance; // After absorb, the glow should fade to nothing. mGlowAlphaFinish = 0.f; mGlowScaleYFinish = 0.f; mDistanceFinish = 0.f; break; case STATE_PULL: mState = STATE_PULL_DECAY; Loading @@ -470,10 +543,12 @@ public class EdgeEffect { mGlowAlphaStart = mGlowAlpha; mGlowScaleYStart = mGlowScaleY; mDistanceStart = mDistance; // After pull, the glow should fade to nothing. mGlowAlphaFinish = 0.f; mGlowScaleYFinish = 0.f; mDistanceFinish = 0.f; break; case STATE_PULL_DECAY: mState = STATE_RECEDE; Loading @@ -484,4 +559,20 @@ public class EdgeEffect { } } } /** * @return The estimated pull distance as calculated from mGlowScaleY. */ private float calculateDistanceFromGlowValues(float scale, float alpha) { if (scale >= 1f) { // It should asymptotically approach 1, but not reach there. // Here, we're just choosing a value that is large. return 1f; } if (scale > 0f) { float v = 1f / 0.7f / (mGlowScaleY - 1f); return v * v / mBounds.height(); } return alpha / PULL_DISTANCE_ALPHA_GLOW_FACTOR; } }