am a83c5806: Merge "SwipeDismissLayout makes activity opaque only after entry animation ends." into lmp-sprout-dev automerge: 96c5d37

* commit 'a83c5806ded083f51549ba4bf70e0c1f6a17fc61':
  SwipeDismissLayout makes activity opaque only after entry animation ends.
This commit is contained in:
Filip Gruszczynski
2014-11-21 10:21:19 +00:00
committed by Android Git Automerger
4 changed files with 92 additions and 8 deletions

View File

@@ -5619,6 +5619,16 @@ public class Activity extends ContextThemeWrapper
public void onEnterAnimationComplete() { public void onEnterAnimationComplete() {
} }
/**
* @hide
*/
public void dispatchEnterAnimationComplete() {
onEnterAnimationComplete();
if (getWindow() != null && getWindow().getDecorView() != null) {
getWindow().getDecorView().getViewTreeObserver().dispatchOnEnterAnimationComplete();
}
}
/** /**
* Adjust the current immersive mode setting. * Adjust the current immersive mode setting.
* *

View File

@@ -2536,7 +2536,7 @@ public final class ActivityThread {
private void handleEnterAnimationComplete(IBinder token) { private void handleEnterAnimationComplete(IBinder token) {
ActivityClientRecord r = mActivities.get(token); ActivityClientRecord r = mActivities.get(token);
if (r != null) { if (r != null) {
r.activity.onEnterAnimationComplete(); r.activity.dispatchEnterAnimationComplete();
} }
} }

View File

@@ -37,6 +37,8 @@ public final class ViewTreeObserver {
private CopyOnWriteArrayList<OnWindowAttachListener> mOnWindowAttachListeners; private CopyOnWriteArrayList<OnWindowAttachListener> mOnWindowAttachListeners;
private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners; private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners;
private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners; private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
private CopyOnWriteArrayList<OnEnterAnimationCompleteListener>
mOnEnterAnimationCompleteListeners;
// Non-recursive listeners use CopyOnWriteArray // Non-recursive listeners use CopyOnWriteArray
// Any listener invoked from ViewRootImpl.performTraversals() should not be recursive // Any listener invoked from ViewRootImpl.performTraversals() should not be recursive
@@ -315,6 +317,13 @@ public final class ViewTreeObserver {
public void onComputeInternalInsets(InternalInsetsInfo inoutInfo); public void onComputeInternalInsets(InternalInsetsInfo inoutInfo);
} }
/**
* @hide
*/
public interface OnEnterAnimationCompleteListener {
public void onEnterAnimationComplete();
}
/** /**
* Creates a new ViewTreeObserver. This constructor should not be called * Creates a new ViewTreeObserver. This constructor should not be called
*/ */
@@ -780,6 +789,29 @@ public final class ViewTreeObserver {
mOnComputeInternalInsetsListeners.remove(victim); 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() { private void checkIsAlive() {
if (!mAlive) { if (!mAlive) {
throw new IllegalStateException("This ViewTreeObserver is not alive, call " throw new IllegalStateException("This ViewTreeObserver is not alive, call "
@@ -1021,6 +1053,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 * 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 * iterate over this array at any given time. This class avoids allocations

View File

@@ -26,6 +26,7 @@ import android.view.VelocityTracker;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator; import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@@ -76,6 +77,19 @@ public class SwipeDismissLayout extends FrameLayout {
private OnDismissedListener mDismissedListener; private OnDismissedListener mDismissedListener;
private OnSwipeProgressChangedListener mProgressListener; 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; private float mLastX;
@@ -103,13 +117,6 @@ public class SwipeDismissLayout extends FrameLayout {
android.R.integer.config_shortAnimTime); android.R.integer.config_shortAnimTime);
mCancelInterpolator = new DecelerateInterpolator(1.5f); mCancelInterpolator = new DecelerateInterpolator(1.5f);
mDismissInterpolator = new AccelerateInterpolator(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) { public void setOnDismissedListener(OnDismissedListener listener) {
@@ -120,6 +127,24 @@ public class SwipeDismissLayout extends FrameLayout {
mProgressListener = listener; mProgressListener = listener;
} }
@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 @Override
public boolean onInterceptTouchEvent(MotionEvent ev) { public boolean onInterceptTouchEvent(MotionEvent ev) {
// offset because the view is translated during swipe // offset because the view is translated during swipe