Using ViewPropertyAnimator for animations
Replacing some use of fastInvalidate/setFast* methods with ViewPropertyAnimator animations Change-Id: Id5a8934b38d9ae3a95b6dccb431f9787839d2927
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user