Using ViewPropertyAnimator for animations

Replacing some use of fastInvalidate/setFast*
methods with ViewPropertyAnimator animations

Change-Id: Id5a8934b38d9ae3a95b6dccb431f9787839d2927
This commit is contained in:
Michael Jurka
2011-12-12 21:48:38 -08:00
parent 25595a611a
commit 7407d2a16e
3 changed files with 315 additions and 76 deletions
+16 -13
View File
@@ -2226,14 +2226,13 @@ public final class Launcher extends Activity
mWorkspace.getChangeStateAnimation(Workspace.State.SMALL, animated);
if (animated) {
final ValueAnimator scaleAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
scaleAnim.setInterpolator(new Workspace.ZoomOutInterpolator());
scaleAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
public void onAnimationUpdate(float a, float b) {
toView.setScaleX(a * scale + b * 1f);
toView.setScaleY(a * scale + b * 1f);
}
});
toView.setScaleX(scale);
toView.setScaleY(scale);
final LauncherViewPropertyAnimator scaleAnim = new LauncherViewPropertyAnimator(toView);
scaleAnim.
scaleX(1f).scaleY(1f).
setDuration(duration).
setInterpolator(new Workspace.ZoomOutInterpolator());
toView.setVisibility(View.VISIBLE);
toView.setAlpha(0f);
@@ -2248,8 +2247,8 @@ public final class Launcher extends Activity
// toView should appear right at the end of the workspace shrink
// animation
mStateAnimation = new AnimatorSet();
mStateAnimation.play(alphaAnim).after(startDelay);
mStateAnimation.play(scaleAnim).after(startDelay);
mStateAnimation.play(alphaAnim).after(startDelay);
mStateAnimation.addListener(new AnimatorListenerAdapter() {
boolean animationCancelled = false;
@@ -2579,8 +2578,10 @@ public final class Launcher extends Activity
void showHotseat(boolean animated) {
if (!LauncherApplication.isScreenLarge()) {
if (animated) {
int duration = mSearchDropTargetBar.getTransitionInDuration();
mHotseat.animate().alpha(1f).setDuration(duration);
if (mHotseat.getAlpha() != 1f) {
int duration = mSearchDropTargetBar.getTransitionInDuration();
mHotseat.animate().alpha(1f).setDuration(duration);
}
} else {
mHotseat.setAlpha(1f);
}
@@ -2593,8 +2594,10 @@ public final class Launcher extends Activity
void hideHotseat(boolean animated) {
if (!LauncherApplication.isScreenLarge()) {
if (animated) {
int duration = mSearchDropTargetBar.getTransitionOutDuration();
mHotseat.animate().alpha(0f).setDuration(duration);
if (mHotseat.getAlpha() != 0f) {
int duration = mSearchDropTargetBar.getTransitionOutDuration();
mHotseat.animate().alpha(0f).setDuration(duration);
}
} else {
mHotseat.setAlpha(0f);
}
@@ -0,0 +1,255 @@
/*
* Copyright (C) 2012 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.launcher2;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.TimeInterpolator;
import android.view.ViewPropertyAnimator;
import android.view.View;
import java.util.ArrayList;
import java.util.EnumSet;
public class LauncherViewPropertyAnimator extends Animator implements AnimatorListener {
enum Properties {
TRANSLATION_X,
TRANSLATION_Y,
SCALE_X,
SCALE_Y,
ROTATION_Y,
ALPHA,
START_DELAY,
DURATION,
INTERPOLATOR
}
EnumSet<Properties> mPropertiesToSet = EnumSet.noneOf(Properties.class);
ViewPropertyAnimator mViewPropertyAnimator;
View mTarget;
float mTranslationX;
float mTranslationY;
float mScaleX;
float mScaleY;
float mRotationY;
float mAlpha;
long mStartDelay;
long mDuration;
TimeInterpolator mInterpolator;
Animator.AnimatorListener mListener;
boolean mRunning = false;
public LauncherViewPropertyAnimator(View target) {
mTarget = target;
}
@Override
public void addListener(Animator.AnimatorListener listener) {
if (mListener != null) {
throw new RuntimeException("Only one listener supported");
}
mListener = listener;
}
@Override
public void cancel() {
mViewPropertyAnimator.cancel();
}
@Override
public Animator clone() {
throw new RuntimeException("Not implemented");
}
@Override
public void end() {
throw new RuntimeException("Not implemented");
}
@Override
public long getDuration() {
return mViewPropertyAnimator.getDuration();
}
@Override
public ArrayList<Animator.AnimatorListener> getListeners() {
return null;
}
@Override
public long getStartDelay() {
return mViewPropertyAnimator.getStartDelay();
}
@Override
public void onAnimationCancel(Animator animation) {
if (mListener != null) {
mListener.onAnimationCancel(this);
}
mRunning = false;
}
@Override
public void onAnimationEnd(Animator animation) {
if (mListener != null) {
mListener.onAnimationEnd(this);
}
mRunning = false;
}
@Override
public void onAnimationRepeat(Animator animation) {
if (mListener != null) {
mListener.onAnimationRepeat(this);
}
}
@Override
public void onAnimationStart(Animator animation) {
if (mListener != null) {
mListener.onAnimationStart(this);
}
mRunning = true;
}
@Override
public boolean isRunning() {
return mRunning;
}
@Override
public boolean isStarted() {
return mViewPropertyAnimator != null;
}
@Override
public void removeAllListeners() {
mListener = null;
}
@Override
public void removeListener(Animator.AnimatorListener listener) {
if (mListener == listener) {
mListener = null;
} else {
throw new RuntimeException("Removing listener that wasn't set");
}
}
@Override
public Animator setDuration(long duration) {
mPropertiesToSet.add(Properties.DURATION);
mDuration = duration;
return this;
}
@Override
public void setInterpolator(TimeInterpolator value) {
mPropertiesToSet.add(Properties.INTERPOLATOR);
mInterpolator = value;
}
@Override
public void setStartDelay(long startDelay) {
mPropertiesToSet.add(Properties.START_DELAY);
mStartDelay = startDelay;
}
@Override
public void setTarget(Object target) {
throw new RuntimeException("Not implemented");
}
@Override
public void setupEndValues() {
}
@Override
public void setupStartValues() {
}
@Override
public void start() {
mViewPropertyAnimator = mTarget.animate();
if (mPropertiesToSet.contains(Properties.TRANSLATION_X)) {
mViewPropertyAnimator.translationX(mTranslationX);
}
if (mPropertiesToSet.contains(Properties.TRANSLATION_Y)) {
mViewPropertyAnimator.translationY(mTranslationY);
}
if (mPropertiesToSet.contains(Properties.SCALE_X)) {
mViewPropertyAnimator.scaleX(mScaleX);
}
if (mPropertiesToSet.contains(Properties.ROTATION_Y)) {
mViewPropertyAnimator.rotationY(mRotationY);
}
if (mPropertiesToSet.contains(Properties.SCALE_Y)) {
mViewPropertyAnimator.scaleY(mScaleY);
}
if (mPropertiesToSet.contains(Properties.ALPHA)) {
mViewPropertyAnimator.alpha(mAlpha);
}
if (mPropertiesToSet.contains(Properties.START_DELAY)) {
mViewPropertyAnimator.setStartDelay(mStartDelay);
}
if (mPropertiesToSet.contains(Properties.DURATION)) {
mViewPropertyAnimator.setDuration(mDuration);
}
if (mPropertiesToSet.contains(Properties.INTERPOLATOR)) {
mViewPropertyAnimator.setInterpolator(mInterpolator);
}
mViewPropertyAnimator.setListener(this);
mViewPropertyAnimator.start();
}
public LauncherViewPropertyAnimator translationX(float value) {
mPropertiesToSet.add(Properties.TRANSLATION_X);
mTranslationX = value;
return this;
}
public LauncherViewPropertyAnimator translationY(float value) {
mPropertiesToSet.add(Properties.TRANSLATION_Y);
mTranslationY = value;
return this;
}
public LauncherViewPropertyAnimator scaleX(float value) {
mPropertiesToSet.add(Properties.SCALE_X);
mScaleX = value;
return this;
}
public LauncherViewPropertyAnimator scaleY(float value) {
mPropertiesToSet.add(Properties.SCALE_Y);
mScaleY = value;
return this;
}
public LauncherViewPropertyAnimator rotationY(float value) {
mPropertiesToSet.add(Properties.ROTATION_Y);
mRotationY = value;
return this;
}
public LauncherViewPropertyAnimator alpha(float value) {
mPropertiesToSet.add(Properties.ALPHA);
mAlpha = value;
return this;
}
}
+44 -63
View File
@@ -57,7 +57,6 @@ import android.view.Display;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
@@ -1635,14 +1634,7 @@ public class Workspace extends SmoothPagedView
}
if (animated) {
ValueAnimator animWithInterpolator =
ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
if (zoomIn) {
animWithInterpolator.setInterpolator(mZoomInInterpolator);
}
animWithInterpolator.addListener(new AnimatorListenerAdapter() {
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(android.animation.Animator animation) {
// The above code to determine initialAlpha and finalAlpha will ensure that only
@@ -1657,10 +1649,11 @@ public class Workspace extends SmoothPagedView
}
}
});
for (int i = 0; i < getChildCount(); i++) {
for (int index = 0; index < getChildCount(); index++) {
final int i = index;
final CellLayout cl = (CellLayout) getChildAt(i);
invalidate();
if (mOldAlphas[i] == 0 && mNewAlphas[i] == 0) {
final CellLayout cl = (CellLayout) getChildAt(i);
cl.fastInvalidate();
cl.setFastTranslationX(mNewTranslationXs[i]);
cl.setFastTranslationY(mNewTranslationYs[i]);
@@ -1669,60 +1662,48 @@ public class Workspace extends SmoothPagedView
cl.setFastBackgroundAlpha(mNewBackgroundAlphas[i]);
cl.setBackgroundAlphaMultiplier(mNewBackgroundAlphaMultipliers[i]);
cl.setFastAlpha(mNewAlphas[i]);
} else {
LauncherViewPropertyAnimator a = new LauncherViewPropertyAnimator(cl);
a.translationX(mNewTranslationXs[i])
.translationY(mNewTranslationYs[i])
.scaleX(mNewScaleXs[i])
.scaleY(mNewScaleYs[i])
.setDuration(duration)
.setInterpolator(mZoomInInterpolator);
if (mOldAlphas[i] != mNewAlphas[i]) {
a.alpha(mNewAlphas[i]);
}
anim.play(a);
if (mOldRotationYs[i] != 0 || mNewRotationYs[i] != 0) {
ValueAnimator rotate = ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
rotate.setInterpolator(new DecelerateInterpolator(2.0f));
rotate.addUpdateListener(new LauncherAnimatorUpdateListener() {
public void onAnimationUpdate(float a, float b) {
cl.setRotationY(a * 0f + b * 1f);
}
});
anim.play(rotate);
}
if (mOldBackgroundAlphas[i] != 0 ||
mNewBackgroundAlphas[i] != 0 ||
mOldBackgroundAlphaMultipliers[i] != 0 ||
mNewBackgroundAlphaMultipliers[i] != 0) {
ValueAnimator bgAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
bgAnim.setInterpolator(mZoomInInterpolator);
bgAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
public void onAnimationUpdate(float a, float b) {
cl.setFastBackgroundAlpha(
a * mOldBackgroundAlphas[i] +
b * mNewBackgroundAlphas[i]);
cl.setBackgroundAlphaMultiplier(
a * mOldBackgroundAlphaMultipliers[i] +
b * mNewBackgroundAlphaMultipliers[i]);
}
});
anim.play(bgAnim);
}
}
}
animWithInterpolator.addUpdateListener(new LauncherAnimatorUpdateListener() {
public void onAnimationUpdate(float a, float b) {
mTransitionProgress = b;
if (b == 0f) {
// an optimization, but not required
return;
}
invalidate();
for (int i = 0; i < getChildCount(); i++) {
if (mOldAlphas[i] != 0 || mNewAlphas[i] != 0) {
final CellLayout cl = (CellLayout) getChildAt(i);
cl.fastInvalidate();
cl.setFastTranslationX(
a * mOldTranslationXs[i] + b * mNewTranslationXs[i]);
cl.setFastTranslationY(
a * mOldTranslationYs[i] + b * mNewTranslationYs[i]);
cl.setFastScaleX(a * mOldScaleXs[i] + b * mNewScaleXs[i]);
cl.setFastScaleY(a * mOldScaleYs[i] + b * mNewScaleYs[i]);
cl.setFastBackgroundAlpha(
a * mOldBackgroundAlphas[i] + b * mNewBackgroundAlphas[i]);
cl.setBackgroundAlphaMultiplier(a * mOldBackgroundAlphaMultipliers[i] +
b * mNewBackgroundAlphaMultipliers[i]);
cl.setFastAlpha(a * mOldAlphas[i] + b * mNewAlphas[i]);
if (mOldAlphas[i] != mNewAlphas[i]) {
cl.setAlpha(a * mOldAlphas[i] + b * mNewAlphas[i]);
}
}
}
}
});
ValueAnimator rotationAnim =
ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
rotationAnim.setInterpolator(new DecelerateInterpolator(2.0f));
rotationAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
public void onAnimationUpdate(float a, float b) {
if (b == 0f) {
// an optimization, but not required
return;
}
for (int i = 0; i < getChildCount(); i++) {
if (mOldAlphas[i] != 0 || mNewAlphas[i] != 0 ||
mOldRotationYs[i] != 0 || mNewRotationYs[i] != 0) {
final CellLayout cl = (CellLayout) getChildAt(i);
cl.setFastRotationY(a * mOldRotationYs[i] + b * mNewRotationYs[i]);
}
}
}
});
anim.playTogether(animWithInterpolator, rotationAnim);
anim.setStartDelay(delay);
// If we call this when we're not animated, onAnimationEnd is never called on
// the listener; make sure we only use the listener when we're actually animating