VectorDrawable native rendering - Step 5 of MANY

Implemented reset() (public API for AVD)
and reverse() (internal API that needs to be supported)

Change-Id: Ife1650049f271cad1347943151a5800c40c20aa2
This commit is contained in:
Doris Liu
2016-02-02 14:14:04 -08:00
parent 7f036f8bce
commit 18bdf443e3
10 changed files with 304 additions and 169 deletions

View File

@@ -238,9 +238,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
mAnimatorSet.recordLastSeenTarget((DisplayListCanvas) canvas);
}
mAnimatedVectorState.mVectorDrawable.draw(canvas);
if (isStarted()) {
invalidateSelf();
}
}
@Override
@@ -611,10 +608,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
return mAnimatorSet.isRunning();
}
private boolean isStarted() {
return mAnimatorSet.isStarted();
}
/**
* Resets the AnimatedVectorDrawable to the start state as specified in the animators.
*/
@@ -626,12 +619,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
@Override
public void start() {
ensureAnimatorSet();
// If any one of the animator has not ended, do nothing.
if (isStarted()) {
return;
}
mAnimatorSet.start();
invalidateSelf();
}
@@ -652,6 +639,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
@Override
public void stop() {
mAnimatorSet.end();
invalidateSelf();
}
/**
@@ -774,6 +762,9 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
* @hide
*/
public static class VectorDrawableAnimator {
private static final int NONE = 0;
private static final int START_ANIMATION = 1;
private static final int REVERSE_ANIMATION = 2;
private AnimatorListener mListener = null;
private final LongArray mStartDelays = new LongArray();
private PropertyValuesHolder.PropertyValues mTmpValues =
@@ -782,7 +773,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
private boolean mContainsSequentialAnimators = false;
private boolean mStarted = false;
private boolean mInitialized = false;
private boolean mAnimationPending = false;
private boolean mIsReversible = false;
// This needs to be set before parsing starts.
private boolean mShouldIgnoreInvalidAnim;
@@ -790,7 +780,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
private final VirtualRefBasePtr mSetRefBasePtr;
private WeakReference<RenderNode> mTarget = null;
private WeakReference<RenderNode> mLastSeenTarget = null;
private int mLastListenerId = 0;
private int mPendingAnimationAction = NONE;
VectorDrawableAnimator() {
mSetPtr = nCreateAnimatorSet();
@@ -810,6 +801,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
mInitialized = true;
// Check reversible.
mIsReversible = true;
if (mContainsSequentialAnimators) {
mIsReversible = false;
} else {
@@ -821,7 +813,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
}
}
}
mIsReversible = true;
}
private void parseAnimatorSet(AnimatorSet set, long startTime) {
@@ -1042,27 +1033,22 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
* to the last seen RenderNode target and start right away.
*/
protected void recordLastSeenTarget(DisplayListCanvas canvas) {
if (mAnimationPending) {
mLastSeenTarget = new WeakReference<RenderNode>(
RenderNodeAnimatorSetHelper.getTarget(canvas));
mLastSeenTarget = new WeakReference<RenderNode>(
RenderNodeAnimatorSetHelper.getTarget(canvas));
if (mPendingAnimationAction != NONE) {
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
Log.d(LOGTAG, "Target is set in the next frame");
}
mAnimationPending = false;
start();
} else {
mLastSeenTarget = new WeakReference<RenderNode>(
RenderNodeAnimatorSetHelper.getTarget(canvas));
if (mPendingAnimationAction == START_ANIMATION) {
start();
} else if (mPendingAnimationAction == REVERSE_ANIMATION) {
reverse();
}
mPendingAnimationAction = NONE;
}
}
private boolean setTarget(RenderNode node) {
if (mTarget != null && mTarget.get() != null) {
// TODO: Maybe we want to support target change.
throw new IllegalStateException("Target already set!");
}
node.addAnimator(this);
mTarget = new WeakReference<RenderNode>(node);
return true;
@@ -1081,12 +1067,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
return;
}
if (mStarted) {
return;
}
if (!useLastSeenTarget()) {
mAnimationPending = true;
mPendingAnimationAction = START_ANIMATION;
return;
}
@@ -1094,38 +1076,45 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
Log.d(LOGTAG, "Target is set. Starting VDAnimatorSet from java");
}
nStart(mSetPtr, this);
mStarted = true;
nStart(mSetPtr, this, ++mLastListenerId);
if (mListener != null) {
mListener.onAnimationStart(null);
}
mStarted = true;
}
public void end() {
if (mInitialized && mStarted) {
if (mInitialized && useLastSeenTarget()) {
// If no target has ever been set, no-op
nEnd(mSetPtr);
onAnimationEnd();
}
}
void reset() {
if (!mInitialized) {
return;
public void reset() {
if (mInitialized && useLastSeenTarget()) {
// If no target has ever been set, no-op
nReset(mSetPtr);
}
// TODO: Need to implement reset.
Log.w(LOGTAG, "Reset is yet to be implemented");
nReset(mSetPtr);
}
// Current (imperfect) Java AnimatorSet cannot be reversed when the set contains sequential
// animators or when the animator set has a start delay
void reverse() {
if (!mIsReversible) {
if (!mIsReversible || !mInitialized) {
return;
}
// TODO: Need to support reverse (non-public API)
Log.w(LOGTAG, "Reverse is yet to be implemented");
nReverse(mSetPtr, this);
if (!useLastSeenTarget()) {
mPendingAnimationAction = REVERSE_ANIMATION;
return;
}
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
Log.d(LOGTAG, "Target is set. Reversing VDAnimatorSet from java");
}
mStarted = true;
nReverse(mSetPtr, this, ++mLastListenerId);
if (mListener != null) {
mListener.onAnimationStart(null);
}
}
public long getAnimatorNativePtr() {
@@ -1155,7 +1144,13 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
mListener = null;
}
private void onAnimationEnd() {
private void onAnimationEnd(int listenerId) {
if (listenerId != mLastListenerId) {
return;
}
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
Log.d(LOGTAG, "on finished called from native");
}
mStarted = false;
if (mListener != null) {
mListener.onAnimationEnd(null);
@@ -1164,11 +1159,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
}
// onFinished: should be called from native
private static void callOnFinished(VectorDrawableAnimator set) {
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
Log.d(LOGTAG, "on finished called from native");
}
set.onAnimationEnd();
private static void callOnFinished(VectorDrawableAnimator set, int id) {
set.onAnimationEnd(id);
}
}
@@ -1188,8 +1180,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
private static native long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue,
float endValue);
private static native void nSetPropertyHolderData(long nativePtr, float[] data, int length);
private static native void nStart(long animatorSetPtr, VectorDrawableAnimator set);
private static native void nReverse(long animatorSetPtr, VectorDrawableAnimator set);
private static native void nStart(long animatorSetPtr, VectorDrawableAnimator set, int id);
private static native void nReverse(long animatorSetPtr, VectorDrawableAnimator set, int id);
private static native void nEnd(long animatorSetPtr);
private static native void nReset(long animatorSetPtr);
}