import com.android.launcher.R;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
final float alpha = mAllApps.getAlpha();
ValueAnimator alphaAnim = ObjectAnimator.ofFloat(mAllApps, "alpha", alpha, 0.0f).
setDuration(duration);
- alphaAnim.addListener(new AnimatorListenerAdapter() {
+ alphaAnim.addListener(new LauncherAnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationEndOrCancel(Animator animation) {
String tag = getCurrentTabTag();
if (tag == TAG_ALL) {
mAllApps.setAppFilter(AllAppsPagedView.ALL_APPS_FLAG);
package com.android.launcher2;
-import java.util.Arrays;
+import com.android.launcher.R;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.WallpaperManager;
-import android.content.ClipDescription;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
-import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LayoutAnimationController;
-import com.android.launcher.R;
+import java.util.Arrays;
public class CellLayout extends ViewGroup implements Dimmable {
static final String TAG = "CellLayout";
// The animation holds a reference to the drag outline bitmap as long is it's
// running. This way the bitmap can be GCed when the animations are complete.
anim.getAnimator().addListener(new AnimatorListenerAdapter() {
+ @Override
public void onAnimationEnd(Animator animation) {
if ((Float) ((ValueAnimator) animation).getAnimatedValue() == 0f) {
anim.setTag(null);
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(scaleUp).before(scaleDown);
bouncer.play(scaleUp).with(alphaFadeOut);
- bouncer.addListener(new AnimatorListenerAdapter() {
+ bouncer.addListener(new LauncherAnimatorListenerAdapter() {
+ @Override
public void onAnimationStart(Animator animation) {
setHover(true);
}
- public void onAnimationEnd(Animator animation) {
+ @Override
+ public void onAnimationEndOrCancel(Animator animation) {
setHover(false);
setHoverScale(1.0f);
setHoverAlpha(1.0f);
mOriginalFromValue = fromValue;
mOriginalToValue = toValue;
- mAnimator.addListener(new AnimatorListenerAdapter() {
- public void onAnimationEnd(Animator animation) {
+ mAnimator.addListener(new LauncherAnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEndOrCancel(Animator animation) {
mDirection = STOPPED;
}
});
import com.android.launcher.R;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter;
+import android.content.Intent.ShortcutIconResource;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
-import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.View.OnLongClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TabHost;
-import android.widget.TabHost.OnTabChangeListener;
-import android.widget.TabHost.TabContentFactory;
import android.widget.TextView;
import android.widget.Toast;
+import android.widget.TabHost.OnTabChangeListener;
+import android.widget.TabHost.TabContentFactory;
import java.io.DataInputStream;
import java.io.DataOutputStream;
ValueAnimator alphaAnim = ObjectAnimator.ofFloat(mCustomizePagedView,
"alpha", alpha, 0.0f);
alphaAnim.setDuration(duration);
- alphaAnim.addListener(new AnimatorListenerAdapter() {
+ alphaAnim.addListener(new LauncherAnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationEndOrCancel(Animator animation) {
String tag = mHomeCustomizationDrawer.getCurrentTabTag();
if (tag == WIDGETS_TAG) {
mCustomizePagedView.setCustomizationFilter(
if (seq != null) {
Animator anim = ObjectAnimator.ofFloat(view, "alpha", show ? 1.0f : 0.0f);
anim.setDuration(duration);
- anim.addListener(new AnimatorListenerAdapter() {
+ anim.addListener(new LauncherAnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
if (showing) showToolbarButton(view);
}
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationEndOrCancel(Animator animation) {
if (hiding) hideToolbarButton(view);
}
});
setPivotsForZoom(toView, toState, scale);
- if (toState == State.ALL_APPS) {
+ if (toAllApps) {
mWorkspace.shrinkToBottom(animated);
} else {
mWorkspace.shrinkToTop(animated);
PropertyValuesHolder.ofFloat("scaleY", scale, 1.0f));
scaleAnim.setDuration(duration);
scaleAnim.setInterpolator(new DecelerateInterpolator());
- scaleAnim.addListener(new AnimatorListenerAdapter() {
+ scaleAnim.addListener(new LauncherAnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
// Prepare the position
toView.setTranslationY(0.0f);
toView.setVisibility(View.VISIBLE);
}
+ @Override
+ public void onAnimationEndOrCancel(Animator animation) {
+ // If we don't set the final scale values here, if this animation is cancelled
+ // it will have the wrong scale value and subsequent cameraPan animations will
+ // not fix that
+ toView.setScaleX(1.0f);
+ toView.setScaleY(1.0f);
+ }
});
AnimatorSet toolbarHideAnim = new AnimatorSet();
PropertyValuesHolder.ofFloat("scaleY", scaleFactor));
scaleAnim.setDuration(duration);
scaleAnim.setInterpolator(new AccelerateInterpolator());
- mStateAnimation.addListener(new AnimatorListenerAdapter() {
+ mStateAnimation.addListener(new LauncherAnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationEndOrCancel(Animator animation) {
fromView.setVisibility(View.GONE);
- fromView.setScaleX(1.0f);
- fromView.setScaleY(1.0f);
}
});
if (animated) {
if (mStateAnimation != null) mStateAnimation.cancel();
mStateAnimation = new AnimatorSet();
- mStateAnimation.addListener(new AnimatorListenerAdapter() {
+ mStateAnimation.addListener(new LauncherAnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
toView.setVisibility(View.VISIBLE);
toView.setY(toViewStartY);
}
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationEndOrCancel(Animator animation) {
fromView.setVisibility(View.GONE);
}
});
ObjectAnimator fromAnim = ObjectAnimator.ofFloat(fromView, "y",
fromViewStartY, fromViewEndY);
fromAnim.setDuration(duration);
- ObjectAnimator toAnim = ObjectAnimator.ofFloat(toView, "y",
- toViewStartY, toViewEndY);
+ ObjectAnimator toAnim = ObjectAnimator.ofPropertyValuesHolder(toView,
+ PropertyValuesHolder.ofFloat("y", toViewStartY, toViewEndY),
+ PropertyValuesHolder.ofFloat("scaleX", toView.getScaleX(), 1.0f),
+ PropertyValuesHolder.ofFloat("scaleY", toView.getScaleY(), 1.0f)
+ );
fromAnim.setDuration(duration);
mStateAnimation.playTogether(toolbarHideAnim, fromAnim, toAnim);
fromView.setY(fromViewEndY);
fromView.setVisibility(View.GONE);
toView.setY(toViewEndY);
+ toView.setScaleX(1.0f);
+ toView.setScaleY(1.0f);
toView.setVisibility(View.VISIBLE);
hideAndShowToolbarButtons(toState, null, null);
}
--- /dev/null
+/*
+ * Copyright (C) 2010 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 java.util.HashSet;
+
+/**
+ * This adapter class provides empty implementations of the methods from {@link android.animation.Animator.AnimatorListener}.
+ * Any custom listener that cares only about a subset of the methods of this listener can
+ * simply subclass this adapter class instead of implementing the interface directly.
+ */
+public abstract class LauncherAnimatorListenerAdapter implements Animator.AnimatorListener {
+ HashSet<Animator> cancelled = new HashSet<Animator>();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void onAnimationCancel(Animator animation) {
+ onAnimationEndOrCancel(animation);
+ cancelled.add(animation);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void onAnimationEnd(Animator animation) {
+ if (!cancelled.contains(animation)) onAnimationEndOrCancel(animation);
+ cancelled.remove(animation);
+ }
+
+ /**
+ * Like onAnimationEnd, except it's called immediately in the case on onAnimationCancel, and
+ * it's only called once in that case
+ */
+ public void onAnimationEndOrCancel(Animator animation) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+}
package com.android.launcher2;
-import java.util.ArrayList;
-import java.util.HashSet;
+import com.android.launcher.R;
import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
+import android.animation.Animator.AnimatorListener;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.WallpaperManager;
import android.appwidget.AppWidgetManager;
import android.widget.TextView;
import android.widget.Toast;
-import com.android.launcher.R;
+import java.util.ArrayList;
+import java.util.HashSet;
/**
* The workspace is a wide area with a wallpaper and a finite number of pages.
private ShrinkPosition mShrunkenState;
private boolean mWaitingToShrink = false;
private ShrinkPosition mWaitingToShrinkPosition;
+ private AnimatorSet mAnimator;
private boolean mInScrollArea = false;
private boolean mInDragMode = false;
mExternalDragOutlinePaint.setAntiAlias(true);
setWillNotDraw(false);
- mUnshrinkAnimationListener = new AnimatorListenerAdapter() {
+ mUnshrinkAnimationListener = new LauncherAnimatorListenerAdapter() {
+ @Override
public void onAnimationStart(Animator animation) {
mIsInUnshrinkAnimation = true;
}
- public void onAnimationEnd(Animator animation) {
+ @Override
+ public void onAnimationEndOrCancel(Animator animation) {
mIsInUnshrinkAnimation = false;
}
};
// of the views accordingly
newX -= (pageWidth - scaledPageWidth) / 2.0f;
newY -= (pageHeight - scaledPageHeight) / 2.0f;
+
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
+ mAnimator = new AnimatorSet();
for (int i = 0; i < screenCount; i++) {
CellLayout cl = (CellLayout) getChildAt(i);
PropertyValuesHolder.ofFloat("alpha", finalAlpha),
PropertyValuesHolder.ofFloat("rotationY", rotation));
anim.setDuration(duration);
- anim.start();
+ mAnimator.playTogether(anim);
} else {
cl.setX((int)newX);
cl.setY((int)newY);
// increment newX for the next screen
newX += scaledPageWidth + extraScaledSpacing;
}
+ if (animated) {
+ mAnimator.start();
+ }
setChildrenDrawnWithCacheEnabled(true);
}
void unshrink(boolean animated) {
if (mIsSmall) {
mIsSmall = false;
- AnimatorSet s = new AnimatorSet();
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
+ mAnimator = new AnimatorSet();
final int screenCount = getChildCount();
final int duration = getResources().getInteger(R.integer.config_workspaceUnshrinkTime);
}
if (animated) {
-
- s.playTogether(
+ mAnimator.playTogether(
ObjectAnimator.ofFloat(cl, "translationX", 0.0f).setDuration(duration),
ObjectAnimator.ofFloat(cl, "translationY", 0.0f).setDuration(duration),
ObjectAnimator.ofFloat(cl, "scaleX", 1.0f).setDuration(duration),
if (animated) {
// 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
- s.addListener(mUnshrinkAnimationListener);
- s.start();
+ mAnimator.addListener(mUnshrinkAnimationListener);
+ mAnimator.start();
}
}
}