Merge "Move RenderNodeAnimator to android.graphics.animation package"
This commit is contained in:
committed by
Android (Google) Code Review
commit
db8164c0ac
@@ -16,518 +16,52 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.NonNull;
|
||||
import android.graphics.CanvasProperty;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RecordingCanvas;
|
||||
import android.graphics.RenderNode;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.util.VirtualRefBasePtr;
|
||||
import com.android.internal.view.animation.FallbackLUTInterpolator;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class RenderNodeAnimator extends Animator {
|
||||
// Keep in sync with enum RenderProperty in Animator.h
|
||||
public static final int TRANSLATION_X = 0;
|
||||
public static final int TRANSLATION_Y = 1;
|
||||
public static final int TRANSLATION_Z = 2;
|
||||
public static final int SCALE_X = 3;
|
||||
public static final int SCALE_Y = 4;
|
||||
public static final int ROTATION = 5;
|
||||
public static final int ROTATION_X = 6;
|
||||
public static final int ROTATION_Y = 7;
|
||||
public static final int X = 8;
|
||||
public static final int Y = 9;
|
||||
public static final int Z = 10;
|
||||
public static final int ALPHA = 11;
|
||||
// The last value in the enum, used for array size initialization
|
||||
public static final int LAST_VALUE = ALPHA;
|
||||
public class RenderNodeAnimator extends android.graphics.animation.RenderNodeAnimator
|
||||
implements android.graphics.animation.RenderNodeAnimator.ViewListener {
|
||||
|
||||
// Keep in sync with enum PaintFields in Animator.h
|
||||
public static final int PAINT_STROKE_WIDTH = 0;
|
||||
|
||||
/**
|
||||
* Field for the Paint alpha channel, which should be specified as a value
|
||||
* between 0 and 255.
|
||||
*/
|
||||
public static final int PAINT_ALPHA = 1;
|
||||
|
||||
// ViewPropertyAnimator uses a mask for its values, we need to remap them
|
||||
// to the enum values here. RenderPropertyAnimator can't use the mask values
|
||||
// directly as internally it uses a lookup table so it needs the values to
|
||||
// be sequential starting from 0
|
||||
private static final SparseIntArray sViewPropertyAnimatorMap = new SparseIntArray(15) {{
|
||||
put(ViewPropertyAnimator.TRANSLATION_X, TRANSLATION_X);
|
||||
put(ViewPropertyAnimator.TRANSLATION_Y, TRANSLATION_Y);
|
||||
put(ViewPropertyAnimator.TRANSLATION_Z, TRANSLATION_Z);
|
||||
put(ViewPropertyAnimator.SCALE_X, SCALE_X);
|
||||
put(ViewPropertyAnimator.SCALE_Y, SCALE_Y);
|
||||
put(ViewPropertyAnimator.ROTATION, ROTATION);
|
||||
put(ViewPropertyAnimator.ROTATION_X, ROTATION_X);
|
||||
put(ViewPropertyAnimator.ROTATION_Y, ROTATION_Y);
|
||||
put(ViewPropertyAnimator.X, X);
|
||||
put(ViewPropertyAnimator.Y, Y);
|
||||
put(ViewPropertyAnimator.Z, Z);
|
||||
put(ViewPropertyAnimator.ALPHA, ALPHA);
|
||||
}};
|
||||
|
||||
private VirtualRefBasePtr mNativePtr;
|
||||
|
||||
private Handler mHandler;
|
||||
private RenderNode mTarget;
|
||||
private View mViewTarget;
|
||||
private int mRenderProperty = -1;
|
||||
private float mFinalValue;
|
||||
private TimeInterpolator mInterpolator;
|
||||
|
||||
private static final int STATE_PREPARE = 0;
|
||||
private static final int STATE_DELAYED = 1;
|
||||
private static final int STATE_RUNNING = 2;
|
||||
private static final int STATE_FINISHED = 3;
|
||||
private int mState = STATE_PREPARE;
|
||||
|
||||
private long mUnscaledDuration = 300;
|
||||
private long mUnscaledStartDelay = 0;
|
||||
// If this is true, we will run any start delays on the UI thread. This is
|
||||
// the safe default, and is necessary to ensure start listeners fire at
|
||||
// the correct time. Animators created by RippleDrawable (the
|
||||
// CanvasProperty<> ones) do not have this expectation, and as such will
|
||||
// set this to false so that the renderthread handles the startdelay instead
|
||||
private final boolean mUiThreadHandlesDelay;
|
||||
private long mStartDelay = 0;
|
||||
private long mStartTime;
|
||||
|
||||
public static int mapViewPropertyToRenderProperty(int viewProperty) {
|
||||
return sViewPropertyAnimatorMap.get(viewProperty);
|
||||
}
|
||||
|
||||
public RenderNodeAnimator(int property, float finalValue) {
|
||||
mRenderProperty = property;
|
||||
mFinalValue = finalValue;
|
||||
mUiThreadHandlesDelay = true;
|
||||
init(nCreateAnimator(property, finalValue));
|
||||
super(property, finalValue);
|
||||
}
|
||||
|
||||
public RenderNodeAnimator(CanvasProperty<Float> property, float finalValue) {
|
||||
init(nCreateCanvasPropertyFloatAnimator(
|
||||
property.getNativeContainer(), finalValue));
|
||||
mUiThreadHandlesDelay = false;
|
||||
super(property, finalValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new render node animator for a field on a Paint property.
|
||||
*
|
||||
* @param property The paint property to target
|
||||
* @param paintField Paint field to animate, one of {@link #PAINT_ALPHA} or
|
||||
* {@link #PAINT_STROKE_WIDTH}
|
||||
* @param finalValue The target value for the property
|
||||
*/
|
||||
public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, float finalValue) {
|
||||
init(nCreateCanvasPropertyPaintAnimator(
|
||||
property.getNativeContainer(), paintField, finalValue));
|
||||
mUiThreadHandlesDelay = false;
|
||||
super(property, paintField, finalValue);
|
||||
}
|
||||
|
||||
public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) {
|
||||
init(nCreateRevealAnimator(x, y, startRadius, endRadius));
|
||||
mUiThreadHandlesDelay = true;
|
||||
}
|
||||
|
||||
private void init(long ptr) {
|
||||
mNativePtr = new VirtualRefBasePtr(ptr);
|
||||
}
|
||||
|
||||
private void checkMutable() {
|
||||
if (mState != STATE_PREPARE) {
|
||||
throw new IllegalStateException("Animator has already started, cannot change it now!");
|
||||
}
|
||||
if (mNativePtr == null) {
|
||||
throw new IllegalStateException("Animator's target has been destroyed "
|
||||
+ "(trying to modify an animation after activity destroy?)");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isNativeInterpolator(TimeInterpolator interpolator) {
|
||||
return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class);
|
||||
}
|
||||
|
||||
private void applyInterpolator() {
|
||||
if (mInterpolator == null || mNativePtr == null) return;
|
||||
|
||||
long ni;
|
||||
if (isNativeInterpolator(mInterpolator)) {
|
||||
ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator();
|
||||
} else {
|
||||
long duration = nGetDuration(mNativePtr.get());
|
||||
ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration);
|
||||
}
|
||||
nSetInterpolator(mNativePtr.get(), ni);
|
||||
super(x, y, startRadius, endRadius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (mTarget == null) {
|
||||
throw new IllegalStateException("Missing target!");
|
||||
}
|
||||
|
||||
if (mState != STATE_PREPARE) {
|
||||
throw new IllegalStateException("Already started!");
|
||||
}
|
||||
|
||||
mState = STATE_DELAYED;
|
||||
if (mHandler == null) {
|
||||
mHandler = new Handler(true);
|
||||
}
|
||||
applyInterpolator();
|
||||
|
||||
if (mNativePtr == null) {
|
||||
// It's dead, immediately cancel
|
||||
cancel();
|
||||
} else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
|
||||
nSetStartDelay(mNativePtr.get(), mStartDelay);
|
||||
doStart();
|
||||
} else {
|
||||
getHelper().addDelayedAnimation(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void doStart() {
|
||||
public void onAlphaAnimationStart(float finalAlpha) {
|
||||
// Alpha is a special snowflake that has the canonical value stored
|
||||
// in mTransformationInfo instead of in RenderNode, so we need to update
|
||||
// it with the final value here.
|
||||
if (mRenderProperty == RenderNodeAnimator.ALPHA) {
|
||||
mViewTarget.ensureTransformationInfo();
|
||||
mViewTarget.setAlphaInternal(mFinalValue);
|
||||
}
|
||||
|
||||
moveToRunningState();
|
||||
|
||||
if (mViewTarget != null) {
|
||||
// Kick off a frame to start the process
|
||||
mViewTarget.invalidateViewProperty(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveToRunningState() {
|
||||
mState = STATE_RUNNING;
|
||||
if (mNativePtr != null) {
|
||||
nStart(mNativePtr.get());
|
||||
}
|
||||
notifyStartListeners();
|
||||
}
|
||||
|
||||
private void notifyStartListeners() {
|
||||
final ArrayList<AnimatorListener> listeners = cloneListeners();
|
||||
final int numListeners = listeners == null ? 0 : listeners.size();
|
||||
for (int i = 0; i < numListeners; i++) {
|
||||
listeners.get(i).onAnimationStart(this);
|
||||
}
|
||||
mViewTarget.ensureTransformationInfo();
|
||||
mViewTarget.setAlphaInternal(finalAlpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (mState != STATE_PREPARE && mState != STATE_FINISHED) {
|
||||
if (mState == STATE_DELAYED) {
|
||||
getHelper().removeDelayedAnimation(this);
|
||||
moveToRunningState();
|
||||
}
|
||||
|
||||
final ArrayList<AnimatorListener> listeners = cloneListeners();
|
||||
final int numListeners = listeners == null ? 0 : listeners.size();
|
||||
for (int i = 0; i < numListeners; i++) {
|
||||
listeners.get(i).onAnimationCancel(this);
|
||||
}
|
||||
|
||||
end();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
if (mState != STATE_FINISHED) {
|
||||
if (mState < STATE_RUNNING) {
|
||||
getHelper().removeDelayedAnimation(this);
|
||||
doStart();
|
||||
}
|
||||
if (mNativePtr != null) {
|
||||
nEnd(mNativePtr.get());
|
||||
if (mViewTarget != null) {
|
||||
// Kick off a frame to flush the state change
|
||||
mViewTarget.invalidateViewProperty(true, false);
|
||||
}
|
||||
} else {
|
||||
// It's already dead, jump to onFinish
|
||||
onFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
throw new UnsupportedOperationException();
|
||||
public void invalidateParent(boolean forceRedraw) {
|
||||
mViewTarget.invalidateViewProperty(true, false);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setTarget(View view) {
|
||||
public void setTarget(@NonNull View view) {
|
||||
mViewTarget = view;
|
||||
setViewListener(this);
|
||||
setTarget(mViewTarget.mRenderNode);
|
||||
}
|
||||
|
||||
/** Sets the animation target to the owning view of the RecordingCanvas */
|
||||
public void setTarget(RecordingCanvas canvas) {
|
||||
setTarget(canvas.mNode);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setTarget(DisplayListCanvas canvas) {
|
||||
setTarget((RecordingCanvas) canvas);
|
||||
}
|
||||
|
||||
private void setTarget(RenderNode node) {
|
||||
checkMutable();
|
||||
if (mTarget != null) {
|
||||
throw new IllegalStateException("Target already set!");
|
||||
}
|
||||
nSetListener(mNativePtr.get(), this);
|
||||
mTarget = node;
|
||||
mTarget.addAnimator(this);
|
||||
}
|
||||
|
||||
public void setStartValue(float startValue) {
|
||||
checkMutable();
|
||||
nSetStartValue(mNativePtr.get(), startValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartDelay(long startDelay) {
|
||||
checkMutable();
|
||||
if (startDelay < 0) {
|
||||
throw new IllegalArgumentException("startDelay must be positive; " + startDelay);
|
||||
}
|
||||
mUnscaledStartDelay = startDelay;
|
||||
mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStartDelay() {
|
||||
return mUnscaledStartDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderNodeAnimator setDuration(long duration) {
|
||||
checkMutable();
|
||||
if (duration < 0) {
|
||||
throw new IllegalArgumentException("duration must be positive; " + duration);
|
||||
}
|
||||
mUnscaledDuration = duration;
|
||||
nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDuration() {
|
||||
return mUnscaledDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalDuration() {
|
||||
return mUnscaledDuration + mUnscaledStartDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return mState == STATE_DELAYED || mState == STATE_RUNNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
return mState != STATE_PREPARE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInterpolator(TimeInterpolator interpolator) {
|
||||
checkMutable();
|
||||
mInterpolator = interpolator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeInterpolator getInterpolator() {
|
||||
return mInterpolator;
|
||||
}
|
||||
|
||||
protected void onFinished() {
|
||||
if (mState == STATE_PREPARE) {
|
||||
// Unlikely but possible, the native side has been destroyed
|
||||
// before we have started.
|
||||
releaseNativePtr();
|
||||
return;
|
||||
}
|
||||
if (mState == STATE_DELAYED) {
|
||||
getHelper().removeDelayedAnimation(this);
|
||||
notifyStartListeners();
|
||||
}
|
||||
mState = STATE_FINISHED;
|
||||
|
||||
final ArrayList<AnimatorListener> listeners = cloneListeners();
|
||||
final int numListeners = listeners == null ? 0 : listeners.size();
|
||||
for (int i = 0; i < numListeners; i++) {
|
||||
listeners.get(i).onAnimationEnd(this);
|
||||
}
|
||||
|
||||
// Release the native object, as it has a global reference to us. This
|
||||
// breaks the cyclic reference chain, and allows this object to be
|
||||
// GC'd
|
||||
releaseNativePtr();
|
||||
}
|
||||
|
||||
private void releaseNativePtr() {
|
||||
if (mNativePtr != null) {
|
||||
mNativePtr.release();
|
||||
mNativePtr = null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ArrayList<AnimatorListener> cloneListeners() {
|
||||
ArrayList<AnimatorListener> listeners = getListeners();
|
||||
if (listeners != null) {
|
||||
listeners = (ArrayList<AnimatorListener>) listeners.clone();
|
||||
}
|
||||
return listeners;
|
||||
}
|
||||
|
||||
public long getNativeAnimator() {
|
||||
return mNativePtr.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the animator was started, false if still delayed
|
||||
*/
|
||||
private boolean processDelayed(long frameTimeMs) {
|
||||
if (mStartTime == 0) {
|
||||
mStartTime = frameTimeMs;
|
||||
} else if ((frameTimeMs - mStartTime) >= mStartDelay) {
|
||||
doStart();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static DelayedAnimationHelper getHelper() {
|
||||
DelayedAnimationHelper helper = sAnimationHelper.get();
|
||||
if (helper == null) {
|
||||
helper = new DelayedAnimationHelper();
|
||||
sAnimationHelper.set(helper);
|
||||
}
|
||||
return helper;
|
||||
}
|
||||
|
||||
private static ThreadLocal<DelayedAnimationHelper> sAnimationHelper =
|
||||
new ThreadLocal<DelayedAnimationHelper>();
|
||||
|
||||
private static class DelayedAnimationHelper implements Runnable {
|
||||
|
||||
private ArrayList<RenderNodeAnimator> mDelayedAnims = new ArrayList<RenderNodeAnimator>();
|
||||
private final Choreographer mChoreographer;
|
||||
private boolean mCallbackScheduled;
|
||||
|
||||
public DelayedAnimationHelper() {
|
||||
mChoreographer = Choreographer.getInstance();
|
||||
}
|
||||
|
||||
public void addDelayedAnimation(RenderNodeAnimator animator) {
|
||||
mDelayedAnims.add(animator);
|
||||
scheduleCallback();
|
||||
}
|
||||
|
||||
public void removeDelayedAnimation(RenderNodeAnimator animator) {
|
||||
mDelayedAnims.remove(animator);
|
||||
}
|
||||
|
||||
private void scheduleCallback() {
|
||||
if (!mCallbackScheduled) {
|
||||
mCallbackScheduled = true;
|
||||
mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long frameTimeMs = mChoreographer.getFrameTime();
|
||||
mCallbackScheduled = false;
|
||||
|
||||
int end = 0;
|
||||
for (int i = 0; i < mDelayedAnims.size(); i++) {
|
||||
RenderNodeAnimator animator = mDelayedAnims.get(i);
|
||||
if (!animator.processDelayed(frameTimeMs)) {
|
||||
if (end != i) {
|
||||
mDelayedAnims.set(end, animator);
|
||||
}
|
||||
end++;
|
||||
}
|
||||
}
|
||||
while (mDelayedAnims.size() > end) {
|
||||
mDelayedAnims.remove(mDelayedAnims.size() - 1);
|
||||
}
|
||||
|
||||
if (mDelayedAnims.size() > 0) {
|
||||
scheduleCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called by native
|
||||
private static void callOnFinished(RenderNodeAnimator animator) {
|
||||
if (animator.mHandler != null) {
|
||||
animator.mHandler.post(animator::onFinished);
|
||||
} else {
|
||||
new Handler(Looper.getMainLooper(), null, true).post(animator::onFinished);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator clone() {
|
||||
throw new IllegalStateException("Cannot clone this animator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllowRunningAsynchronously(boolean mayRunAsync) {
|
||||
checkMutable();
|
||||
nSetAllowRunningAsync(mNativePtr.get(), mayRunAsync);
|
||||
}
|
||||
|
||||
private static native long nCreateAnimator(int property, float finalValue);
|
||||
private static native long nCreateCanvasPropertyFloatAnimator(
|
||||
long canvasProperty, float finalValue);
|
||||
private static native long nCreateCanvasPropertyPaintAnimator(
|
||||
long canvasProperty, int paintField, float finalValue);
|
||||
private static native long nCreateRevealAnimator(
|
||||
int x, int y, float startRadius, float endRadius);
|
||||
|
||||
private static native void nSetStartValue(long nativePtr, float startValue);
|
||||
private static native void nSetDuration(long nativePtr, long duration);
|
||||
private static native long nGetDuration(long nativePtr);
|
||||
private static native void nSetStartDelay(long nativePtr, long startDelay);
|
||||
private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
|
||||
private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync);
|
||||
private static native void nSetListener(long animPtr, RenderNodeAnimator listener);
|
||||
|
||||
private static native void nStart(long animPtr);
|
||||
private static native void nEnd(long animPtr);
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.view;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.graphics.RecordingCanvas;
|
||||
import android.graphics.RenderNode;
|
||||
|
||||
import com.android.internal.view.animation.FallbackLUTInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* This is a helper class to get access to methods and fields needed for RenderNodeAnimatorSet
|
||||
* that are internal or package private to android.view package.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class RenderNodeAnimatorSetHelper {
|
||||
|
||||
/** checkstyle @hide */
|
||||
public static RenderNode getTarget(RecordingCanvas recordingCanvas) {
|
||||
return recordingCanvas.mNode;
|
||||
}
|
||||
|
||||
/** checkstyle @hide */
|
||||
public static long createNativeInterpolator(TimeInterpolator interpolator, long
|
||||
duration) {
|
||||
if (interpolator == null) {
|
||||
// create LinearInterpolator
|
||||
return NativeInterpolatorFactoryHelper.createLinearInterpolator();
|
||||
} else if (RenderNodeAnimator.isNativeInterpolator(interpolator)) {
|
||||
return ((NativeInterpolatorFactory)interpolator).createNativeInterpolator();
|
||||
} else {
|
||||
return FallbackLUTInterpolator.createNativeInterpolator(interpolator, duration);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,19 +17,18 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the rate of change starts and ends slowly but
|
||||
* accelerates through the middle.
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class AccelerateDecelerateInterpolator extends BaseInterpolator
|
||||
implements NativeInterpolatorFactory {
|
||||
implements NativeInterpolator {
|
||||
public AccelerateDecelerateInterpolator() {
|
||||
}
|
||||
|
||||
@@ -44,6 +43,6 @@ public class AccelerateDecelerateInterpolator extends BaseInterpolator
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
|
||||
return NativeInterpolatorFactory.createAccelerateDecelerateInterpolator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the rate of change starts out slowly and
|
||||
@@ -33,7 +33,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
*
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class AccelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
|
||||
public class AccelerateInterpolator extends BaseInterpolator implements NativeInterpolator {
|
||||
private final float mFactor;
|
||||
private final double mDoubleFactor;
|
||||
|
||||
@@ -85,6 +85,6 @@ public class AccelerateInterpolator extends BaseInterpolator implements NativeIn
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createAccelerateInterpolator(mFactor);
|
||||
return NativeInterpolatorFactory.createAccelerateInterpolator(mFactor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,18 +20,18 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the change starts backward then flings forward.
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class AnticipateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
|
||||
public class AnticipateInterpolator extends BaseInterpolator implements NativeInterpolator {
|
||||
private final float mTension;
|
||||
|
||||
public AnticipateInterpolator() {
|
||||
@@ -73,6 +73,6 @@ public class AnticipateInterpolator extends BaseInterpolator implements NativeIn
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createAnticipateInterpolator(mTension);
|
||||
return NativeInterpolatorFactory.createAnticipateInterpolator(mTension);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +24,11 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the change starts backward then flings forward and overshoots
|
||||
@@ -36,7 +36,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class AnticipateOvershootInterpolator extends BaseInterpolator
|
||||
implements NativeInterpolatorFactory {
|
||||
implements NativeInterpolator {
|
||||
private final float mTension;
|
||||
|
||||
public AnticipateOvershootInterpolator() {
|
||||
@@ -103,6 +103,6 @@ public class AnticipateOvershootInterpolator extends BaseInterpolator
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createAnticipateOvershootInterpolator(mTension);
|
||||
return NativeInterpolatorFactory.createAnticipateOvershootInterpolator(mTension);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the change bounces at the end.
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class BounceInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
|
||||
public class BounceInterpolator extends BaseInterpolator implements NativeInterpolator {
|
||||
public BounceInterpolator() {
|
||||
}
|
||||
|
||||
@@ -56,6 +55,6 @@ public class BounceInterpolator extends BaseInterpolator implements NativeInterp
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createBounceInterpolator();
|
||||
return NativeInterpolatorFactory.createBounceInterpolator();
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,12 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* Repeats the animation for a specified number of cycles. The
|
||||
@@ -33,7 +33,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
*
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class CycleInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
|
||||
public class CycleInterpolator extends BaseInterpolator implements NativeInterpolator {
|
||||
public CycleInterpolator(float cycles) {
|
||||
mCycles = cycles;
|
||||
}
|
||||
@@ -65,6 +65,6 @@ public class CycleInterpolator extends BaseInterpolator implements NativeInterpo
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createCycleInterpolator(mCycles);
|
||||
return NativeInterpolatorFactory.createCycleInterpolator(mCycles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the rate of change starts out quickly and
|
||||
@@ -33,7 +33,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
*
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class DecelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
|
||||
public class DecelerateInterpolator extends BaseInterpolator implements NativeInterpolator {
|
||||
public DecelerateInterpolator() {
|
||||
}
|
||||
|
||||
@@ -81,6 +81,6 @@ public class DecelerateInterpolator extends BaseInterpolator implements NativeIn
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createDecelerateInterpolator(mFactor);
|
||||
return NativeInterpolatorFactory.createDecelerateInterpolator(mFactor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the rate of change is constant
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
|
||||
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolator {
|
||||
|
||||
public LinearInterpolator() {
|
||||
}
|
||||
@@ -42,6 +41,6 @@ public class LinearInterpolator extends BaseInterpolator implements NativeInterp
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createLinearInterpolator();
|
||||
return NativeInterpolatorFactory.createLinearInterpolator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,19 +20,19 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the change flings forward and overshoots the last value
|
||||
* then comes back.
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class OvershootInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
|
||||
public class OvershootInterpolator extends BaseInterpolator implements NativeInterpolator {
|
||||
private final float mTension;
|
||||
|
||||
public OvershootInterpolator() {
|
||||
@@ -76,6 +76,6 @@ public class OvershootInterpolator extends BaseInterpolator implements NativeInt
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createOvershootInterpolator(mTension);
|
||||
return NativeInterpolatorFactory.createOvershootInterpolator(mTension);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@ import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.animation.HasNativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolator;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.PathParser;
|
||||
import android.view.InflateException;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator that can traverse a Path that extends from <code>Point</code>
|
||||
@@ -46,7 +46,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
* </pre></blockquote></p>
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class PathInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
|
||||
public class PathInterpolator extends BaseInterpolator implements NativeInterpolator {
|
||||
|
||||
// This governs how accurate the approximation of the Path is.
|
||||
private static final float PRECISION = 0.002f;
|
||||
@@ -237,7 +237,7 @@ public class PathInterpolator extends BaseInterpolator implements NativeInterpol
|
||||
/** @hide **/
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createPathInterpolator(mX, mY);
|
||||
return NativeInterpolatorFactory.createPathInterpolator(mX, mY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.view.animation;
|
||||
|
||||
/**
|
||||
* Static utility class for constructing native interpolators to keep the
|
||||
* JNI simpler
|
||||
*/
|
||||
public final class NativeInterpolatorFactoryHelper {
|
||||
private NativeInterpolatorFactoryHelper() {}
|
||||
|
||||
public static native long createAccelerateDecelerateInterpolator();
|
||||
public static native long createAccelerateInterpolator(float factor);
|
||||
public static native long createAnticipateInterpolator(float tension);
|
||||
public static native long createAnticipateOvershootInterpolator(float tension);
|
||||
public static native long createBounceInterpolator();
|
||||
public static native long createCycleInterpolator(float cycles);
|
||||
public static native long createDecelerateInterpolator(float factor);
|
||||
public static native long createLinearInterpolator();
|
||||
public static native long createOvershootInterpolator(float tension);
|
||||
public static native long createPathInterpolator(float[] x, float[] y);
|
||||
public static native long createLutInterpolator(float[] values);
|
||||
}
|
||||
@@ -42,9 +42,7 @@ cc_library_shared {
|
||||
"android_util_StringBlock.cpp",
|
||||
"android_util_XmlBlock.cpp",
|
||||
"android_util_jar_StrictJarFile.cpp",
|
||||
"android_view_RenderNodeAnimator.cpp",
|
||||
"com_android_internal_util_VirtualRefBasePtr.cpp",
|
||||
"com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp",
|
||||
],
|
||||
|
||||
include_dirs: [
|
||||
@@ -351,6 +349,8 @@ cc_library_static {
|
||||
"android/graphics/apex/android_paint.cpp",
|
||||
"android/graphics/apex/android_region.cpp",
|
||||
|
||||
"android_graphics_animation_NativeInterpolatorFactory.cpp",
|
||||
"android_graphics_animation_RenderNodeAnimator.cpp",
|
||||
"android_graphics_Canvas.cpp",
|
||||
"android_graphics_ColorSpace.cpp",
|
||||
"android_graphics_drawable_AnimatedVectorDrawable.cpp",
|
||||
|
||||
@@ -119,13 +119,11 @@ extern int register_android_graphics_BLASTBufferQueue(JNIEnv* env);
|
||||
extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
|
||||
extern int register_android_view_InputApplicationHandle(JNIEnv* env);
|
||||
extern int register_android_view_InputWindowHandle(JNIEnv* env);
|
||||
extern int register_android_view_RenderNodeAnimator(JNIEnv* env);
|
||||
extern int register_android_view_Surface(JNIEnv* env);
|
||||
extern int register_android_view_SurfaceControl(JNIEnv* env);
|
||||
extern int register_android_view_SurfaceSession(JNIEnv* env);
|
||||
extern int register_android_view_CompositionSamplingListener(JNIEnv* env);
|
||||
extern int register_android_view_TextureView(JNIEnv* env);
|
||||
extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
|
||||
extern int register_android_database_CursorWindow(JNIEnv* env);
|
||||
extern int register_android_database_SQLiteConnection(JNIEnv* env);
|
||||
extern int register_android_database_SQLiteGlobal(JNIEnv* env);
|
||||
@@ -1461,7 +1459,6 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_os_VintfRuntimeInfo),
|
||||
REG_JNI(register_android_service_DataLoaderService),
|
||||
REG_JNI(register_android_view_DisplayEventReceiver),
|
||||
REG_JNI(register_android_view_RenderNodeAnimator),
|
||||
REG_JNI(register_android_view_InputApplicationHandle),
|
||||
REG_JNI(register_android_view_InputWindowHandle),
|
||||
REG_JNI(register_android_view_Surface),
|
||||
@@ -1469,7 +1466,6 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_view_SurfaceSession),
|
||||
REG_JNI(register_android_view_CompositionSamplingListener),
|
||||
REG_JNI(register_android_view_TextureView),
|
||||
REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper),
|
||||
REG_JNI(register_com_google_android_gles_jni_EGLImpl),
|
||||
REG_JNI(register_com_google_android_gles_jni_GLImpl),
|
||||
REG_JNI(register_android_opengl_jni_EGL14),
|
||||
|
||||
@@ -65,6 +65,8 @@ extern int register_android_graphics_Path(JNIEnv* env);
|
||||
extern int register_android_graphics_PathMeasure(JNIEnv* env);
|
||||
extern int register_android_graphics_Picture(JNIEnv* env);
|
||||
extern int register_android_graphics_Region(JNIEnv* env);
|
||||
extern int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env);
|
||||
extern int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env);
|
||||
extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env);
|
||||
extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
|
||||
extern int register_android_graphics_fonts_Font(JNIEnv* env);
|
||||
@@ -82,10 +84,8 @@ extern int register_android_util_Log(JNIEnv* env);
|
||||
extern int register_android_util_PathParser(JNIEnv* env);
|
||||
extern int register_android_util_jar_StrictJarFile(JNIEnv* env);
|
||||
extern int register_android_view_RenderNode(JNIEnv* env);
|
||||
extern int register_android_view_RenderNodeAnimator(JNIEnv* env);
|
||||
extern int register_android_view_DisplayListCanvas(JNIEnv* env);
|
||||
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
|
||||
extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
|
||||
|
||||
#define REG_JNI(name) { name }
|
||||
struct RegJNIRec {
|
||||
@@ -130,6 +130,10 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
|
||||
{"android.graphics.Region", REG_JNI(register_android_graphics_Region)},
|
||||
{"android.graphics.Shader", REG_JNI(register_android_graphics_Shader)},
|
||||
{"android.graphics.Typeface", REG_JNI(register_android_graphics_Typeface)},
|
||||
{"android.graphics.animation.NativeInterpolatorFactory",
|
||||
REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory)},
|
||||
{"android.graphics.animation.RenderNodeAnimator",
|
||||
REG_JNI(register_android_graphics_animation_RenderNodeAnimator)},
|
||||
{"android.graphics.drawable.AnimatedVectorDrawable",
|
||||
REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable)},
|
||||
{"android.graphics.drawable.VectorDrawable",
|
||||
@@ -151,11 +155,8 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
|
||||
{"android.util.Log", REG_JNI(register_android_util_Log)},
|
||||
{"android.util.PathParser", REG_JNI(register_android_util_PathParser)},
|
||||
{"android.util.jar.StrictJarFile", REG_JNI(register_android_util_jar_StrictJarFile)},
|
||||
{"android.view.RenderNodeAnimator", REG_JNI(register_android_view_RenderNodeAnimator)},
|
||||
{"com.android.internal.util.VirtualRefBasePtr",
|
||||
REG_JNI(register_com_android_internal_util_VirtualRefBasePtr)},
|
||||
{"com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
|
||||
REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper)},
|
||||
};
|
||||
// Vector to store the names of classes that need delegates of their native methods
|
||||
static vector<string> classesToDelegate;
|
||||
|
||||
@@ -60,6 +60,8 @@ extern int register_android_graphics_PathMeasure(JNIEnv* env);
|
||||
extern int register_android_graphics_Picture(JNIEnv*);
|
||||
extern int register_android_graphics_Region(JNIEnv* env);
|
||||
extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
|
||||
extern int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env);
|
||||
extern int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env);
|
||||
extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env);
|
||||
extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
|
||||
extern int register_android_graphics_fonts_Font(JNIEnv* env);
|
||||
@@ -123,6 +125,8 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_graphics_SurfaceTexture),
|
||||
REG_JNI(register_android_graphics_Typeface),
|
||||
REG_JNI(register_android_graphics_YuvImage),
|
||||
REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory),
|
||||
REG_JNI(register_android_graphics_animation_RenderNodeAnimator),
|
||||
REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable),
|
||||
REG_JNI(register_android_graphics_drawable_VectorDrawable),
|
||||
REG_JNI(register_android_graphics_fonts_Font),
|
||||
|
||||
@@ -90,7 +90,7 @@ static jlong createLutInterpolator(JNIEnv* env, jobject clazz, jfloatArray jlut)
|
||||
// JNI Glue
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const char* const kClassPathName = "com/android/internal/view/animation/NativeInterpolatorFactoryHelper";
|
||||
const char* const kClassPathName = "android/graphics/animation/NativeInterpolatorFactory";
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{ "createAccelerateDecelerateInterpolator", "()J", (void*) createAccelerateDecelerateInterpolator },
|
||||
@@ -106,7 +106,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{ "createLutInterpolator", "([F)J", (void*) createLutInterpolator },
|
||||
};
|
||||
|
||||
int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv* env) {
|
||||
int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env) {
|
||||
return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ static void end(JNIEnv* env, jobject clazz, jlong animatorPtr) {
|
||||
// JNI Glue
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const char* const kClassPathName = "android/view/RenderNodeAnimator";
|
||||
const char* const kClassPathName = "android/graphics/animation/RenderNodeAnimator";
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{ "nCreateAnimator", "(IF)J", (void*) createAnimator },
|
||||
@@ -203,12 +203,12 @@ static const JNINativeMethod gMethods[] = {
|
||||
{ "nSetStartDelay", "(JJ)V", (void*) setStartDelay },
|
||||
{ "nSetInterpolator", "(JJ)V", (void*) setInterpolator },
|
||||
{ "nSetAllowRunningAsync", "(JZ)V", (void*) setAllowRunningAsync },
|
||||
{ "nSetListener", "(JLandroid/view/RenderNodeAnimator;)V", (void*) setListener},
|
||||
{ "nSetListener", "(JLandroid/graphics/animation/RenderNodeAnimator;)V", (void*) setListener},
|
||||
{ "nStart", "(J)V", (void*) start},
|
||||
{ "nEnd", "(J)V", (void*) end },
|
||||
};
|
||||
|
||||
int register_android_view_RenderNodeAnimator(JNIEnv* env) {
|
||||
int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env) {
|
||||
sLifecycleChecker.incStrong(0);
|
||||
gRenderNodeAnimatorClassInfo.clazz = FindClassOrDie(env, kClassPathName);
|
||||
gRenderNodeAnimatorClassInfo.clazz = MakeGlobalRefOrDie(env,
|
||||
@@ -216,7 +216,7 @@ int register_android_view_RenderNodeAnimator(JNIEnv* env) {
|
||||
|
||||
gRenderNodeAnimatorClassInfo.callOnFinished = GetStaticMethodIDOrDie(
|
||||
env, gRenderNodeAnimatorClassInfo.clazz, "callOnFinished",
|
||||
"(Landroid/view/RenderNodeAnimator;)V");
|
||||
"(Landroid/graphics/animation/RenderNodeAnimator;)V");
|
||||
|
||||
return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
|
||||
}
|
||||
@@ -22,8 +22,8 @@ import android.annotation.FloatRange;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.animation.RenderNodeAnimator;
|
||||
import android.view.NativeVectorDrawableAnimator;
|
||||
import android.view.RenderNodeAnimator;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.view.animation;
|
||||
package android.graphics.animation;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.util.TimeUtils;
|
||||
@@ -26,14 +26,15 @@ import android.view.Choreographer;
|
||||
* with {@link HasNativeInterpolator}
|
||||
*
|
||||
* This implements TimeInterpolator to allow for easier interop with Animators
|
||||
* @hide
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class FallbackLUTInterpolator implements NativeInterpolatorFactory, TimeInterpolator {
|
||||
public class FallbackLUTInterpolator implements NativeInterpolator, TimeInterpolator {
|
||||
|
||||
// If the duration of an animation is more than 300 frames, we cap the sample size to 300.
|
||||
private static final int MAX_SAMPLE_POINTS = 300;
|
||||
private TimeInterpolator mSourceInterpolator;
|
||||
private final float mLut[];
|
||||
private final float[] mLut;
|
||||
|
||||
/**
|
||||
* Used to cache the float[] LUT for use across multiple native
|
||||
@@ -50,7 +51,7 @@ public class FallbackLUTInterpolator implements NativeInterpolatorFactory, TimeI
|
||||
// We need 2 frame values as the minimal.
|
||||
int numAnimFrames = Math.max(2, (int) Math.ceil(((double) duration) / animIntervalMs));
|
||||
numAnimFrames = Math.min(numAnimFrames, MAX_SAMPLE_POINTS);
|
||||
float values[] = new float[numAnimFrames];
|
||||
float[] values = new float[numAnimFrames];
|
||||
float lastFrame = numAnimFrames - 1;
|
||||
for (int i = 0; i < numAnimFrames; i++) {
|
||||
float inValue = i / lastFrame;
|
||||
@@ -61,7 +62,7 @@ public class FallbackLUTInterpolator implements NativeInterpolatorFactory, TimeI
|
||||
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createLutInterpolator(mLut);
|
||||
return NativeInterpolatorFactory.createLutInterpolator(mLut);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +70,7 @@ public class FallbackLUTInterpolator implements NativeInterpolatorFactory, TimeI
|
||||
*/
|
||||
public static long createNativeInterpolator(TimeInterpolator interpolator, long duration) {
|
||||
float[] lut = createLUT(interpolator, duration);
|
||||
return NativeInterpolatorFactoryHelper.createLutInterpolator(lut);
|
||||
return NativeInterpolatorFactory.createLutInterpolator(lut);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.view.animation;
|
||||
package android.graphics.animation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -23,10 +23,10 @@ import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This is a class annotation that signals that it is safe to create
|
||||
* a native interpolator counterpart via {@link NativeInterpolatorFactory}
|
||||
* a native interpolator counterpart via {@link NativeInterpolator}
|
||||
*
|
||||
* The idea here is to prevent subclasses of interpolators from being treated as a
|
||||
* NativeInterpolatorFactory, and instead have them fall back to the LUT & LERP
|
||||
* NativeInterpolator, and instead have them fall back to the LUT & LERP
|
||||
* method like a custom interpolator.
|
||||
*
|
||||
* @hide
|
||||
@@ -14,8 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.view.animation;
|
||||
package android.graphics.animation;
|
||||
|
||||
public interface NativeInterpolatorFactory {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public interface NativeInterpolator {
|
||||
/**
|
||||
* Generates a native interpolator object that can be used by HardwareRenderer to draw
|
||||
* RenderNodes.
|
||||
* @return ptr to native object
|
||||
*/
|
||||
long createNativeInterpolator();
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.graphics.animation;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
|
||||
/**
|
||||
* Static utility class for constructing native interpolators to keep the
|
||||
* JNI simpler
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class NativeInterpolatorFactory {
|
||||
private NativeInterpolatorFactory() {}
|
||||
|
||||
/**
|
||||
* Create a native interpolator from the provided param generating a LUT variant if a native
|
||||
* implementation does not exist.
|
||||
*/
|
||||
public static long createNativeInterpolator(TimeInterpolator interpolator, long
|
||||
duration) {
|
||||
if (interpolator == null) {
|
||||
return createLinearInterpolator();
|
||||
} else if (RenderNodeAnimator.isNativeInterpolator(interpolator)) {
|
||||
return ((NativeInterpolator) interpolator).createNativeInterpolator();
|
||||
} else {
|
||||
return FallbackLUTInterpolator.createNativeInterpolator(interpolator, duration);
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates a specialized native interpolator for Accelerate/Decelerate */
|
||||
public static native long createAccelerateDecelerateInterpolator();
|
||||
/** Creates a specialized native interpolator for Accelerate */
|
||||
public static native long createAccelerateInterpolator(float factor);
|
||||
/** Creates a specialized native interpolator for Anticipate */
|
||||
public static native long createAnticipateInterpolator(float tension);
|
||||
/** Creates a specialized native interpolator for Anticipate with Overshoot */
|
||||
public static native long createAnticipateOvershootInterpolator(float tension);
|
||||
/** Creates a specialized native interpolator for Bounce */
|
||||
public static native long createBounceInterpolator();
|
||||
/** Creates a specialized native interpolator for Cycle */
|
||||
public static native long createCycleInterpolator(float cycles);
|
||||
/** Creates a specialized native interpolator for Decelerate */
|
||||
public static native long createDecelerateInterpolator(float factor);
|
||||
/** Creates a specialized native interpolator for Linear interpolation */
|
||||
public static native long createLinearInterpolator();
|
||||
/** Creates a specialized native interpolator for Overshoot */
|
||||
public static native long createOvershootInterpolator(float tension);
|
||||
/** Creates a specialized native interpolator for along traveling along a Path */
|
||||
public static native long createPathInterpolator(float[] x, float[] y);
|
||||
/** Creates a specialized native interpolator for LUT */
|
||||
public static native long createLutInterpolator(float[] values);
|
||||
}
|
||||
513
graphics/java/android/graphics/animation/RenderNodeAnimator.java
Normal file
513
graphics/java/android/graphics/animation/RenderNodeAnimator.java
Normal file
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.graphics.animation;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.graphics.CanvasProperty;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RecordingCanvas;
|
||||
import android.graphics.RenderNode;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.Choreographer;
|
||||
|
||||
import com.android.internal.util.VirtualRefBasePtr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class RenderNodeAnimator extends Animator {
|
||||
// Keep in sync with enum RenderProperty in Animator.h
|
||||
public static final int TRANSLATION_X = 0;
|
||||
public static final int TRANSLATION_Y = 1;
|
||||
public static final int TRANSLATION_Z = 2;
|
||||
public static final int SCALE_X = 3;
|
||||
public static final int SCALE_Y = 4;
|
||||
public static final int ROTATION = 5;
|
||||
public static final int ROTATION_X = 6;
|
||||
public static final int ROTATION_Y = 7;
|
||||
public static final int X = 8;
|
||||
public static final int Y = 9;
|
||||
public static final int Z = 10;
|
||||
public static final int ALPHA = 11;
|
||||
// The last value in the enum, used for array size initialization
|
||||
public static final int LAST_VALUE = ALPHA;
|
||||
|
||||
// Keep in sync with enum PaintFields in Animator.h
|
||||
public static final int PAINT_STROKE_WIDTH = 0;
|
||||
|
||||
/**
|
||||
* Field for the Paint alpha channel, which should be specified as a value
|
||||
* between 0 and 255.
|
||||
*/
|
||||
public static final int PAINT_ALPHA = 1;
|
||||
|
||||
private VirtualRefBasePtr mNativePtr;
|
||||
|
||||
private Handler mHandler;
|
||||
private RenderNode mTarget;
|
||||
private ViewListener mViewListener;
|
||||
private int mRenderProperty = -1;
|
||||
private float mFinalValue;
|
||||
private TimeInterpolator mInterpolator;
|
||||
|
||||
private static final int STATE_PREPARE = 0;
|
||||
private static final int STATE_DELAYED = 1;
|
||||
private static final int STATE_RUNNING = 2;
|
||||
private static final int STATE_FINISHED = 3;
|
||||
private int mState = STATE_PREPARE;
|
||||
|
||||
private long mUnscaledDuration = 300;
|
||||
private long mUnscaledStartDelay = 0;
|
||||
// If this is true, we will run any start delays on the UI thread. This is
|
||||
// the safe default, and is necessary to ensure start listeners fire at
|
||||
// the correct time. Animators created by RippleDrawable (the
|
||||
// CanvasProperty<> ones) do not have this expectation, and as such will
|
||||
// set this to false so that the renderthread handles the startdelay instead
|
||||
private final boolean mUiThreadHandlesDelay;
|
||||
private long mStartDelay = 0;
|
||||
private long mStartTime;
|
||||
|
||||
/**
|
||||
* Interface used by the view system to update the view hierarchy in conjunction
|
||||
* with this animator.
|
||||
*/
|
||||
public interface ViewListener {
|
||||
/** notify the listener that an alpha animation has begun. */
|
||||
void onAlphaAnimationStart(float finalAlpha);
|
||||
/** notify the listener that the animator has mutated a value that requires invalidation */
|
||||
void invalidateParent(boolean forceRedraw);
|
||||
}
|
||||
|
||||
public RenderNodeAnimator(int property, float finalValue) {
|
||||
mRenderProperty = property;
|
||||
mFinalValue = finalValue;
|
||||
mUiThreadHandlesDelay = true;
|
||||
init(nCreateAnimator(property, finalValue));
|
||||
}
|
||||
|
||||
public RenderNodeAnimator(CanvasProperty<Float> property, float finalValue) {
|
||||
init(nCreateCanvasPropertyFloatAnimator(
|
||||
property.getNativeContainer(), finalValue));
|
||||
mUiThreadHandlesDelay = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new render node animator for a field on a Paint property.
|
||||
*
|
||||
* @param property The paint property to target
|
||||
* @param paintField Paint field to animate, one of {@link #PAINT_ALPHA} or
|
||||
* {@link #PAINT_STROKE_WIDTH}
|
||||
* @param finalValue The target value for the property
|
||||
*/
|
||||
public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, float finalValue) {
|
||||
init(nCreateCanvasPropertyPaintAnimator(
|
||||
property.getNativeContainer(), paintField, finalValue));
|
||||
mUiThreadHandlesDelay = false;
|
||||
}
|
||||
|
||||
public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) {
|
||||
init(nCreateRevealAnimator(x, y, startRadius, endRadius));
|
||||
mUiThreadHandlesDelay = true;
|
||||
}
|
||||
|
||||
private void init(long ptr) {
|
||||
mNativePtr = new VirtualRefBasePtr(ptr);
|
||||
}
|
||||
|
||||
private void checkMutable() {
|
||||
if (mState != STATE_PREPARE) {
|
||||
throw new IllegalStateException("Animator has already started, cannot change it now!");
|
||||
}
|
||||
if (mNativePtr == null) {
|
||||
throw new IllegalStateException("Animator's target has been destroyed "
|
||||
+ "(trying to modify an animation after activity destroy?)");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isNativeInterpolator(TimeInterpolator interpolator) {
|
||||
return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class);
|
||||
}
|
||||
|
||||
private void applyInterpolator() {
|
||||
if (mInterpolator == null || mNativePtr == null) return;
|
||||
|
||||
long ni;
|
||||
if (isNativeInterpolator(mInterpolator)) {
|
||||
ni = ((NativeInterpolator) mInterpolator).createNativeInterpolator();
|
||||
} else {
|
||||
long duration = nGetDuration(mNativePtr.get());
|
||||
ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration);
|
||||
}
|
||||
nSetInterpolator(mNativePtr.get(), ni);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (mTarget == null) {
|
||||
throw new IllegalStateException("Missing target!");
|
||||
}
|
||||
|
||||
if (mState != STATE_PREPARE) {
|
||||
throw new IllegalStateException("Already started!");
|
||||
}
|
||||
|
||||
mState = STATE_DELAYED;
|
||||
if (mHandler == null) {
|
||||
mHandler = new Handler(true);
|
||||
}
|
||||
applyInterpolator();
|
||||
|
||||
if (mNativePtr == null) {
|
||||
// It's dead, immediately cancel
|
||||
cancel();
|
||||
} else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
|
||||
nSetStartDelay(mNativePtr.get(), mStartDelay);
|
||||
doStart();
|
||||
} else {
|
||||
getHelper().addDelayedAnimation(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void doStart() {
|
||||
// Alpha is a special snowflake that has the canonical value stored
|
||||
// in mTransformationInfo instead of in RenderNode, so we need to update
|
||||
// it with the final value here.
|
||||
if (mRenderProperty == RenderNodeAnimator.ALPHA && mViewListener != null) {
|
||||
mViewListener.onAlphaAnimationStart(mFinalValue);
|
||||
}
|
||||
|
||||
moveToRunningState();
|
||||
|
||||
if (mViewListener != null) {
|
||||
// Kick off a frame to start the process
|
||||
mViewListener.invalidateParent(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveToRunningState() {
|
||||
mState = STATE_RUNNING;
|
||||
if (mNativePtr != null) {
|
||||
nStart(mNativePtr.get());
|
||||
}
|
||||
notifyStartListeners();
|
||||
}
|
||||
|
||||
private void notifyStartListeners() {
|
||||
final ArrayList<AnimatorListener> listeners = cloneListeners();
|
||||
final int numListeners = listeners == null ? 0 : listeners.size();
|
||||
for (int i = 0; i < numListeners; i++) {
|
||||
listeners.get(i).onAnimationStart(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (mState != STATE_PREPARE && mState != STATE_FINISHED) {
|
||||
if (mState == STATE_DELAYED) {
|
||||
getHelper().removeDelayedAnimation(this);
|
||||
moveToRunningState();
|
||||
}
|
||||
|
||||
final ArrayList<AnimatorListener> listeners = cloneListeners();
|
||||
final int numListeners = listeners == null ? 0 : listeners.size();
|
||||
for (int i = 0; i < numListeners; i++) {
|
||||
listeners.get(i).onAnimationCancel(this);
|
||||
}
|
||||
|
||||
end();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
if (mState != STATE_FINISHED) {
|
||||
if (mState < STATE_RUNNING) {
|
||||
getHelper().removeDelayedAnimation(this);
|
||||
doStart();
|
||||
}
|
||||
if (mNativePtr != null) {
|
||||
nEnd(mNativePtr.get());
|
||||
if (mViewListener != null) {
|
||||
// Kick off a frame to flush the state change
|
||||
mViewListener.invalidateParent(false);
|
||||
}
|
||||
} else {
|
||||
// It's already dead, jump to onFinish
|
||||
onFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setViewListener(ViewListener listener) {
|
||||
mViewListener = listener;
|
||||
}
|
||||
|
||||
/** Sets the animation target to the owning view of the RecordingCanvas */
|
||||
public final void setTarget(RecordingCanvas canvas) {
|
||||
setTarget(canvas.mNode);
|
||||
}
|
||||
|
||||
/** Sets the node that is to be the target of this animation */
|
||||
protected void setTarget(RenderNode node) {
|
||||
checkMutable();
|
||||
if (mTarget != null) {
|
||||
throw new IllegalStateException("Target already set!");
|
||||
}
|
||||
nSetListener(mNativePtr.get(), this);
|
||||
mTarget = node;
|
||||
mTarget.addAnimator(this);
|
||||
}
|
||||
|
||||
/** Set the start value for the animation */
|
||||
public void setStartValue(float startValue) {
|
||||
checkMutable();
|
||||
nSetStartValue(mNativePtr.get(), startValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartDelay(long startDelay) {
|
||||
checkMutable();
|
||||
if (startDelay < 0) {
|
||||
throw new IllegalArgumentException("startDelay must be positive; " + startDelay);
|
||||
}
|
||||
mUnscaledStartDelay = startDelay;
|
||||
mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStartDelay() {
|
||||
return mUnscaledStartDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderNodeAnimator setDuration(long duration) {
|
||||
checkMutable();
|
||||
if (duration < 0) {
|
||||
throw new IllegalArgumentException("duration must be positive; " + duration);
|
||||
}
|
||||
mUnscaledDuration = duration;
|
||||
nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDuration() {
|
||||
return mUnscaledDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalDuration() {
|
||||
return mUnscaledDuration + mUnscaledStartDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return mState == STATE_DELAYED || mState == STATE_RUNNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
return mState != STATE_PREPARE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInterpolator(TimeInterpolator interpolator) {
|
||||
checkMutable();
|
||||
mInterpolator = interpolator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeInterpolator getInterpolator() {
|
||||
return mInterpolator;
|
||||
}
|
||||
|
||||
protected void onFinished() {
|
||||
if (mState == STATE_PREPARE) {
|
||||
// Unlikely but possible, the native side has been destroyed
|
||||
// before we have started.
|
||||
releaseNativePtr();
|
||||
return;
|
||||
}
|
||||
if (mState == STATE_DELAYED) {
|
||||
getHelper().removeDelayedAnimation(this);
|
||||
notifyStartListeners();
|
||||
}
|
||||
mState = STATE_FINISHED;
|
||||
|
||||
final ArrayList<AnimatorListener> listeners = cloneListeners();
|
||||
final int numListeners = listeners == null ? 0 : listeners.size();
|
||||
for (int i = 0; i < numListeners; i++) {
|
||||
listeners.get(i).onAnimationEnd(this);
|
||||
}
|
||||
|
||||
// Release the native object, as it has a global reference to us. This
|
||||
// breaks the cyclic reference chain, and allows this object to be
|
||||
// GC'd
|
||||
releaseNativePtr();
|
||||
}
|
||||
|
||||
private void releaseNativePtr() {
|
||||
if (mNativePtr != null) {
|
||||
mNativePtr.release();
|
||||
mNativePtr = null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ArrayList<AnimatorListener> cloneListeners() {
|
||||
ArrayList<AnimatorListener> listeners = getListeners();
|
||||
if (listeners != null) {
|
||||
listeners = (ArrayList<AnimatorListener>) listeners.clone();
|
||||
}
|
||||
return listeners;
|
||||
}
|
||||
|
||||
public long getNativeAnimator() {
|
||||
return mNativePtr.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the animator was started, false if still delayed
|
||||
*/
|
||||
private boolean processDelayed(long frameTimeMs) {
|
||||
if (mStartTime == 0) {
|
||||
mStartTime = frameTimeMs;
|
||||
} else if ((frameTimeMs - mStartTime) >= mStartDelay) {
|
||||
doStart();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static DelayedAnimationHelper getHelper() {
|
||||
DelayedAnimationHelper helper = sAnimationHelper.get();
|
||||
if (helper == null) {
|
||||
helper = new DelayedAnimationHelper();
|
||||
sAnimationHelper.set(helper);
|
||||
}
|
||||
return helper;
|
||||
}
|
||||
|
||||
private static ThreadLocal<DelayedAnimationHelper> sAnimationHelper =
|
||||
new ThreadLocal<DelayedAnimationHelper>();
|
||||
|
||||
private static class DelayedAnimationHelper implements Runnable {
|
||||
|
||||
private ArrayList<RenderNodeAnimator> mDelayedAnims = new ArrayList<RenderNodeAnimator>();
|
||||
private final Choreographer mChoreographer;
|
||||
private boolean mCallbackScheduled;
|
||||
|
||||
DelayedAnimationHelper() {
|
||||
mChoreographer = Choreographer.getInstance();
|
||||
}
|
||||
|
||||
public void addDelayedAnimation(RenderNodeAnimator animator) {
|
||||
mDelayedAnims.add(animator);
|
||||
scheduleCallback();
|
||||
}
|
||||
|
||||
public void removeDelayedAnimation(RenderNodeAnimator animator) {
|
||||
mDelayedAnims.remove(animator);
|
||||
}
|
||||
|
||||
private void scheduleCallback() {
|
||||
if (!mCallbackScheduled) {
|
||||
mCallbackScheduled = true;
|
||||
mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long frameTimeMs = mChoreographer.getFrameTime();
|
||||
mCallbackScheduled = false;
|
||||
|
||||
int end = 0;
|
||||
for (int i = 0; i < mDelayedAnims.size(); i++) {
|
||||
RenderNodeAnimator animator = mDelayedAnims.get(i);
|
||||
if (!animator.processDelayed(frameTimeMs)) {
|
||||
if (end != i) {
|
||||
mDelayedAnims.set(end, animator);
|
||||
}
|
||||
end++;
|
||||
}
|
||||
}
|
||||
while (mDelayedAnims.size() > end) {
|
||||
mDelayedAnims.remove(mDelayedAnims.size() - 1);
|
||||
}
|
||||
|
||||
if (mDelayedAnims.size() > 0) {
|
||||
scheduleCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called by native
|
||||
private static void callOnFinished(RenderNodeAnimator animator) {
|
||||
if (animator.mHandler != null) {
|
||||
animator.mHandler.post(animator::onFinished);
|
||||
} else {
|
||||
new Handler(Looper.getMainLooper(), null, true).post(animator::onFinished);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator clone() {
|
||||
throw new IllegalStateException("Cannot clone this animator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllowRunningAsynchronously(boolean mayRunAsync) {
|
||||
checkMutable();
|
||||
nSetAllowRunningAsync(mNativePtr.get(), mayRunAsync);
|
||||
}
|
||||
|
||||
private static native long nCreateAnimator(int property, float finalValue);
|
||||
private static native long nCreateCanvasPropertyFloatAnimator(
|
||||
long canvasProperty, float finalValue);
|
||||
private static native long nCreateCanvasPropertyPaintAnimator(
|
||||
long canvasProperty, int paintField, float finalValue);
|
||||
private static native long nCreateRevealAnimator(
|
||||
int x, int y, float startRadius, float endRadius);
|
||||
|
||||
private static native void nSetStartValue(long nativePtr, float startValue);
|
||||
private static native void nSetDuration(long nativePtr, long duration);
|
||||
private static native long nGetDuration(long nativePtr);
|
||||
private static native void nSetStartDelay(long nativePtr, long startDelay);
|
||||
private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
|
||||
private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync);
|
||||
private static native void nSetListener(long animPtr, RenderNodeAnimator listener);
|
||||
|
||||
private static native void nStart(long animPtr);
|
||||
private static native void nEnd(long animPtr);
|
||||
}
|
||||
@@ -42,6 +42,7 @@ import android.graphics.PixelFormat;
|
||||
import android.graphics.RecordingCanvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RenderNode;
|
||||
import android.graphics.animation.NativeInterpolatorFactory;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.util.ArrayMap;
|
||||
@@ -54,7 +55,6 @@ import android.util.Property;
|
||||
import android.util.TimeUtils;
|
||||
import android.view.Choreographer;
|
||||
import android.view.NativeVectorDrawableAnimator;
|
||||
import android.view.RenderNodeAnimatorSetHelper;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.R;
|
||||
@@ -1532,7 +1532,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
||||
long startDelay = extraDelay + animator.getStartDelay();
|
||||
TimeInterpolator interpolator = animator.getInterpolator();
|
||||
long nativeInterpolator =
|
||||
RenderNodeAnimatorSetHelper.createNativeInterpolator(interpolator, duration);
|
||||
NativeInterpolatorFactory.createNativeInterpolator(interpolator, duration);
|
||||
|
||||
startDelay *= ValueAnimator.getDurationScale();
|
||||
duration *= ValueAnimator.getDurationScale();
|
||||
@@ -1548,7 +1548,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
||||
* to the last seen RenderNode target and start right away.
|
||||
*/
|
||||
protected void recordLastSeenTarget(RecordingCanvas canvas) {
|
||||
final RenderNode node = RenderNodeAnimatorSetHelper.getTarget(canvas);
|
||||
final RenderNode node = canvas.mNode;
|
||||
mLastSeenTarget = new WeakReference<RenderNode>(node);
|
||||
// Add the animator to the list of animators on every draw
|
||||
if (mInitialized || mPendingAnimationActions.size() > 0) {
|
||||
|
||||
@@ -25,9 +25,9 @@ import android.graphics.CanvasProperty;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RecordingCanvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.animation.RenderNodeAnimator;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.MathUtils;
|
||||
import android.view.RenderNodeAnimator;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
Reference in New Issue
Block a user