Cleaned up QC exit animations
Pressing back button now starts proper exit animation.
Also, window shim dims while scrolling animation occurs. The activity
does not finish() until the shim and scrolling animations have both
finished.
Change-Id: Id79ad86c8ab646027b768ca4b5f62781946ffb8a
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 9533d75..7773598 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -16,6 +16,9 @@
package com.android.contacts.quickcontact;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.app.Activity;
@@ -80,7 +83,6 @@
import com.android.contacts.common.model.dataitem.PhoneDataItem;
import com.android.contacts.common.util.DataStatus;
import com.android.contacts.detail.ContactDetailDisplayUtils;
-import com.android.contacts.common.util.UriUtils;
import com.android.contacts.interactions.CalendarInteractionsLoader;
import com.android.contacts.interactions.CallLogInteractionsLoader;
import com.android.contacts.interactions.ContactDeletionInteraction;
@@ -97,7 +99,6 @@
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -147,6 +148,9 @@
private MultiShrinkScroller mScroller;
private SelectAccountDialogFragmentListener mSelectAccountFragmentListener;
private AsyncTask<Void, Void, Void> mEntriesAndActionsTask;
+ private ColorDrawable mWindowShim;
+ private boolean mIsWaitingForOtherPieceOfExitAnimation;
+ private boolean mIsExitAnimationInProgress;
private static final int MIN_NUM_COMMUNICATION_ENTRIES_SHOWN = 3;
private static final int MIN_NUM_COLLAPSED_RECENT_ENTRIES_SHOWN = 3;
@@ -269,7 +273,11 @@
= new MultiShrinkScrollerListener() {
@Override
public void onScrolledOffBottom() {
- onBackPressed();
+ if (!mIsWaitingForOtherPieceOfExitAnimation) {
+ finish();
+ return;
+ }
+ mIsWaitingForOtherPieceOfExitAnimation = false;
}
@Override
@@ -281,6 +289,28 @@
public void onExitFullscreen() {
updateStatusBarColor();
}
+
+ @Override
+ public void onStartScrollOffBottom() {
+ // Remove the window shim now that we are starting an Activity exit animation.
+ final int duration = getResources().getInteger(android.R.integer.config_shortAnimTime);
+ final ObjectAnimator animator = ObjectAnimator.ofInt(mWindowShim, "alpha", 0xFF, 0);
+ animator.addListener(mExitWindowShimAnimationListener);
+ animator.setDuration(duration).start();
+ mIsWaitingForOtherPieceOfExitAnimation = true;
+ mIsExitAnimationInProgress = true;
+ }
+ };
+
+ final AnimatorListener mExitWindowShimAnimationListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mIsWaitingForOtherPieceOfExitAnimation) {
+ finish();
+ return;
+ }
+ mIsWaitingForOtherPieceOfExitAnimation = false;
+ }
};
@Override
@@ -321,11 +351,11 @@
mHasAlreadyBeenOpened = savedInstanceState != null;
- final ColorDrawable windowShim = new ColorDrawable(SHIM_COLOR);
- getWindow().setBackgroundDrawable(windowShim);
+ mWindowShim = new ColorDrawable(SHIM_COLOR);
+ getWindow().setBackgroundDrawable(mWindowShim);
if (!mHasAlreadyBeenOpened) {
final int duration = getResources().getInteger(android.R.integer.config_shortAnimTime);
- ObjectAnimator.ofInt(windowShim, "alpha", 0, 0xFF).setDuration(duration).start();
+ ObjectAnimator.ofInt(mWindowShim, "alpha", 0, 0xFF).setDuration(duration).start();
}
if (mScroller != null) {
@@ -878,8 +908,9 @@
@Override
public void onBackPressed() {
if (mScroller != null) {
- // TODO: implement exit animation if the scroller isn't already off the screen
- finish();
+ if (!mIsExitAnimationInProgress) {
+ mScroller.scrollOffBottom();
+ }
} else {
super.onBackPressed();
}
diff --git a/src/com/android/contacts/widget/MultiShrinkScroller.java b/src/com/android/contacts/widget/MultiShrinkScroller.java
index e05de0b..03d68ee 100644
--- a/src/com/android/contacts/widget/MultiShrinkScroller.java
+++ b/src/com/android/contacts/widget/MultiShrinkScroller.java
@@ -83,6 +83,8 @@
public interface MultiShrinkScrollerListener {
void onScrolledOffBottom();
+ void onStartScrollOffBottom();
+
void onEnterFullscreen();
void onExitFullscreen();
@@ -102,6 +104,8 @@
// Due to a rounding error, after the animation finished we haven't fully scrolled
// off the screen. Lie to the listener: tell it that we did scroll off the screen.
mListener.onScrolledOffBottom();
+ // No other messages need to be sent to the listener.
+ mListener = null;
}
}
};
@@ -364,17 +368,24 @@
*/
private void snapToBottom(int flingDelta) {
if (-getScroll_ignoreOversizedHeader() - flingDelta > 0) {
- final Interpolator interpolator = new AcceleratingFlingInterpolator(
- EXIT_FLING_ANIMATION_DURATION_MS, getCurrentVelocity(),
- getScrollUntilOffBottom());
- mScroller.forceFinished(true);
- ObjectAnimator translateAnimation = ObjectAnimator.ofInt(this, "scroll",
- getScroll() - getScrollUntilOffBottom());
- translateAnimation.setRepeatCount(0);
- translateAnimation.setInterpolator(interpolator);
- translateAnimation.setDuration(EXIT_FLING_ANIMATION_DURATION_MS);
- translateAnimation.addListener(mSnapToBottomListener);
- translateAnimation.start();
+ scrollOffBottom();
+ }
+ }
+
+ public void scrollOffBottom() {
+ final Interpolator interpolator = new AcceleratingFlingInterpolator(
+ EXIT_FLING_ANIMATION_DURATION_MS, getCurrentVelocity(),
+ getScrollUntilOffBottom());
+ mScroller.forceFinished(true);
+ ObjectAnimator translateAnimation = ObjectAnimator.ofInt(this, "scroll",
+ getScroll() - getScrollUntilOffBottom());
+ translateAnimation.setRepeatCount(0);
+ translateAnimation.setInterpolator(interpolator);
+ translateAnimation.setDuration(EXIT_FLING_ANIMATION_DURATION_MS);
+ translateAnimation.addListener(mSnapToBottomListener);
+ translateAnimation.start();
+ if (mListener != null) {
+ mListener.onStartScrollOffBottom();
}
}
@@ -510,6 +521,9 @@
}
private float getCurrentVelocity() {
+ if (mVelocityTracker == null) {
+ return 0;
+ }
mVelocityTracker.computeCurrentVelocity(PIXELS_PER_SECOND, mMaximumVelocity);
return mVelocityTracker.getYVelocity();
}
@@ -567,11 +581,15 @@
toolbarLayoutParams.topMargin -= delta;
mToolbar.setLayoutParams(toolbarLayoutParams);
- if (mListener != null && getScrollUntilOffBottom() <= 0) {
+ if (getScrollUntilOffBottom() <= 0) {
post(new Runnable() {
@Override
public void run() {
- mListener.onScrolledOffBottom();
+ if (mListener != null) {
+ mListener.onScrolledOffBottom();
+ // No other messages need to be sent to the listener.
+ mListener = null;
+ }
}
});
}