From 83a52031fd5c277d0c6e75da50bf8013e8a70399 Mon Sep 17 00:00:00 2001 From: ztenghui Date: Fri, 29 May 2015 17:19:41 -0700 Subject: Setup the animation callback for AnimatedVectorDrawable b/21341096 Change-Id: I84e20366db21ceaa4f044be3e322f9215bb06ad2 --- .../android/graphics/drawable/Animatable2.java | 61 +++++++++++ .../graphics/drawable/AnimatedVectorDrawable.java | 113 +++++++++++++++------ 2 files changed, 141 insertions(+), 33 deletions(-) create mode 100644 graphics/java/android/graphics/drawable/Animatable2.java (limited to 'graphics') diff --git a/graphics/java/android/graphics/drawable/Animatable2.java b/graphics/java/android/graphics/drawable/Animatable2.java new file mode 100644 index 0000000..7c7e60e --- /dev/null +++ b/graphics/java/android/graphics/drawable/Animatable2.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 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.drawable; + +import android.annotation.NonNull; + +/** + * Abstract class that drawables supporting animations and callbacks should extend. + */ +public interface Animatable2 extends Animatable { + + /** + * Adds a callback to listen to the animation events. + * + * @param callback Callback to add. + */ + void registerAnimationCallback(@NonNull AnimationCallback callback); + + /** + * Removes the specified animation callback. + * + * @param callback Callback to remove. + * @return {@code false} if callback didn't exist in the call back list, or {@code true} if + * callback has been removed successfully. + */ + boolean unregisterAnimationCallback(@NonNull AnimationCallback callback); + + /** + * Removes all existing animation callbacks. + */ + void clearAnimationCallbacks(); + + public static abstract class AnimationCallback { + /** + * Called when the animation starts. + * + * @param drawable The drawable started the animation. + */ + public void onAnimationStart(Drawable drawable) {}; + /** + * Called when the animation ends. + * + * @param drawable The drawable finished the animation. + */ + public void onAnimationEnd(Drawable drawable) {}; + } +} diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 100c2f4..96f86b4 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -16,6 +16,7 @@ package android.graphics.drawable; import android.animation.Animator; import android.animation.AnimatorInflater; +import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.Animator.AnimatorListener; import android.annotation.NonNull; @@ -42,7 +43,6 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; -import java.util.List; /** * This class uses {@link android.animation.ObjectAnimator} and @@ -129,7 +129,7 @@ import java.util.List; * @attr ref android.R.styleable#AnimatedVectorDrawableTarget_name * @attr ref android.R.styleable#AnimatedVectorDrawableTarget_animation */ -public class AnimatedVectorDrawable extends Drawable implements Animatable { +public class AnimatedVectorDrawable extends Drawable implements Animatable2 { private static final String LOGTAG = "AnimatedVectorDrawable"; private static final String ANIMATED_VECTOR = "animated-vector"; @@ -153,6 +153,10 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { private boolean mMutated; + /** Use a internal AnimatorListener to support callbacks during animation events. */ + private ArrayList mAnimationCallbacks = null; + private AnimatorListener mAnimatorListener = null; + public AnimatedVectorDrawable() { this(null, null); } @@ -380,36 +384,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { } } - /** - * Adds a listener to the set of listeners that are sent events through the life of an - * animation. - * - * @param listener the listener to be added to the current set of listeners for this animation. - */ - public void addListener(AnimatorListener listener) { - mAnimatorSet.addListener(listener); - } - - /** - * Removes a listener from the set listening to this animation. - * - * @param listener the listener to be removed from the current set of listeners for this - * animation. - */ - public void removeListener(AnimatorListener listener) { - mAnimatorSet.removeListener(listener); - } - - /** - * Gets the set of {@link android.animation.Animator.AnimatorListener} objects that are currently - * listening for events on this AnimatedVectorDrawable object. - * - * @return List The set of listeners. - */ - public List getListeners() { - return mAnimatorSet.getListeners(); - } - private static class AnimatedVectorDrawableState extends ConstantState { int mChangingConfigurations; VectorDrawable mVectorDrawable; @@ -674,4 +648,77 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { unscheduleSelf(what); } }; -} + + @Override + public void registerAnimationCallback(@NonNull AnimationCallback callback) { + if (callback == null) { + return; + } + + // Add listener accordingly. + if (mAnimationCallbacks == null) { + mAnimationCallbacks = new ArrayList<>(); + } + + mAnimationCallbacks.add(callback); + + if (mAnimatorListener == null) { + // Create a animator listener and trigger the callback events when listener is + // triggered. + mAnimatorListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + ArrayList tmpCallbacks = new ArrayList<>(mAnimationCallbacks); + int size = tmpCallbacks.size(); + for (int i = 0; i < size; i ++) { + tmpCallbacks.get(i).onAnimationStart(AnimatedVectorDrawable.this); + } + } + + @Override + public void onAnimationEnd(Animator animation) { + ArrayList tmpCallbacks = new ArrayList<>(mAnimationCallbacks); + int size = tmpCallbacks.size(); + for (int i = 0; i < size; i ++) { + tmpCallbacks.get(i).onAnimationEnd(AnimatedVectorDrawable.this); + } + } + }; + } + mAnimatorSet.addListener(mAnimatorListener); + } + + // A helper function to clean up the animator listener in the mAnimatorSet. + private void removeAnimatorSetListener() { + if (mAnimatorListener != null) { + mAnimatorSet.removeListener(mAnimatorListener); + mAnimatorListener = null; + } + } + + @Override + public boolean unregisterAnimationCallback(@NonNull AnimationCallback callback) { + if (mAnimationCallbacks == null || callback == null) { + // Nothing to be removed. + return false; + } + boolean removed = mAnimationCallbacks.remove(callback); + + // When the last call back unregistered, remove the listener accordingly. + if (mAnimationCallbacks.size() == 0) { + removeAnimatorSetListener(); + } + return removed; + } + + @Override + public void clearAnimationCallbacks() { + removeAnimatorSetListener(); + if (mAnimationCallbacks == null) { + return; + } + + mAnimationCallbacks.clear(); + } + +} \ No newline at end of file -- cgit v1.1