summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Activity.java10
-rw-r--r--core/java/android/app/ActivityThread.java2
-rw-r--r--core/java/android/view/ViewTreeObserver.java49
-rw-r--r--core/java/com/android/internal/widget/SwipeDismissLayout.java39
4 files changed, 92 insertions, 8 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 148527f..fab88a2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5620,6 +5620,16 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * @hide
+ */
+ public void dispatchEnterAnimationComplete() {
+ onEnterAnimationComplete();
+ if (getWindow() != null && getWindow().getDecorView() != null) {
+ getWindow().getDecorView().getViewTreeObserver().dispatchOnEnterAnimationComplete();
+ }
+ }
+
+ /**
* Adjust the current immersive mode setting.
*
* Note that changing this value will have no effect on the activity's
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 98a096c..b64e724 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2536,7 +2536,7 @@ public final class ActivityThread {
private void handleEnterAnimationComplete(IBinder token) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
- r.activity.onEnterAnimationComplete();
+ r.activity.dispatchEnterAnimationComplete();
}
}
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index b85fec8..521fd31 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -37,6 +37,8 @@ public final class ViewTreeObserver {
private CopyOnWriteArrayList<OnWindowAttachListener> mOnWindowAttachListeners;
private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners;
private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
+ private CopyOnWriteArrayList<OnEnterAnimationCompleteListener>
+ mOnEnterAnimationCompleteListeners;
// Non-recursive listeners use CopyOnWriteArray
// Any listener invoked from ViewRootImpl.performTraversals() should not be recursive
@@ -316,6 +318,13 @@ public final class ViewTreeObserver {
}
/**
+ * @hide
+ */
+ public interface OnEnterAnimationCompleteListener {
+ public void onEnterAnimationComplete();
+ }
+
+ /**
* Creates a new ViewTreeObserver. This constructor should not be called
*/
ViewTreeObserver() {
@@ -780,6 +789,29 @@ public final class ViewTreeObserver {
mOnComputeInternalInsetsListeners.remove(victim);
}
+ /**
+ * @hide
+ */
+ public void addOnEnterAnimationCompleteListener(OnEnterAnimationCompleteListener listener) {
+ checkIsAlive();
+ if (mOnEnterAnimationCompleteListeners == null) {
+ mOnEnterAnimationCompleteListeners =
+ new CopyOnWriteArrayList<OnEnterAnimationCompleteListener>();
+ }
+ mOnEnterAnimationCompleteListeners.add(listener);
+ }
+
+ /**
+ * @hide
+ */
+ public void removeOnEnterAnimationCompleteListener(OnEnterAnimationCompleteListener listener) {
+ checkIsAlive();
+ if (mOnEnterAnimationCompleteListeners == null) {
+ return;
+ }
+ mOnEnterAnimationCompleteListeners.remove(listener);
+ }
+
private void checkIsAlive() {
if (!mAlive) {
throw new IllegalStateException("This ViewTreeObserver is not alive, call "
@@ -1022,6 +1054,23 @@ public final class ViewTreeObserver {
}
/**
+ * @hide
+ */
+ public final void dispatchOnEnterAnimationComplete() {
+ // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
+ // perform the dispatching. The iterator is a safe guard against listeners that
+ // could mutate the list by calling the various add/remove methods. This prevents
+ // the array from being modified while we iterate it.
+ final CopyOnWriteArrayList<OnEnterAnimationCompleteListener> listeners =
+ mOnEnterAnimationCompleteListeners;
+ if (listeners != null && !listeners.isEmpty()) {
+ for (OnEnterAnimationCompleteListener listener : listeners) {
+ listener.onEnterAnimationComplete();
+ }
+ }
+ }
+
+ /**
* Copy on write array. This array is not thread safe, and only one loop can
* iterate over this array at any given time. This class avoids allocations
* until a concurrent modification happens.
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index 99b1bae..d617c05 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -26,6 +26,7 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
@@ -76,6 +77,19 @@ public class SwipeDismissLayout extends FrameLayout {
private OnDismissedListener mDismissedListener;
private OnSwipeProgressChangedListener mProgressListener;
+ private ViewTreeObserver.OnEnterAnimationCompleteListener mOnEnterAnimationCompleteListener =
+ new ViewTreeObserver.OnEnterAnimationCompleteListener() {
+ @Override
+ public void onEnterAnimationComplete() {
+ // SwipeDismissLayout assumes that the host Activity is translucent
+ // and temporarily disables translucency when it is fully visible.
+ // As soon as the user starts swiping, we will re-enable
+ // translucency.
+ if (getContext() instanceof Activity) {
+ ((Activity) getContext()).convertFromTranslucent();
+ }
+ }
+ };
private float mLastX;
@@ -103,13 +117,6 @@ public class SwipeDismissLayout extends FrameLayout {
android.R.integer.config_shortAnimTime);
mCancelInterpolator = new DecelerateInterpolator(1.5f);
mDismissInterpolator = new AccelerateInterpolator(1.5f);
- // SwipeDismissLayout assumes that the host Activity is translucent
- // and temporarily disables translucency when it is fully visible.
- // As soon as the user starts swiping, we will re-enable
- // translucency.
- if (context instanceof Activity) {
- ((Activity) context).convertFromTranslucent();
- }
}
public void setOnDismissedListener(OnDismissedListener listener) {
@@ -121,6 +128,24 @@ public class SwipeDismissLayout extends FrameLayout {
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (getContext() instanceof Activity) {
+ getViewTreeObserver().addOnEnterAnimationCompleteListener(
+ mOnEnterAnimationCompleteListener);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (getContext() instanceof Activity) {
+ getViewTreeObserver().removeOnEnterAnimationCompleteListener(
+ mOnEnterAnimationCompleteListener);
+ }
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// offset because the view is translated during swipe
ev.offsetLocation(mTranslationX, 0);