Allow delay of showing/hiding shared element when transferring.

Bug 18932344

Change-Id: Ic967551a4dd27967d2312a6c6c8a83b34c220031
This commit is contained in:
George Mount
2015-04-08 14:48:02 -07:00
parent ec3c97d27f
commit bd93e69c8e
5 changed files with 112 additions and 31 deletions

View File

@@ -5310,6 +5310,11 @@ package android.app {
method public void onRejectSharedElements(java.util.List<android.view.View>);
method public void onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
method public void onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
method public void onSharedElementsArrived(java.util.List<java.lang.String>, java.util.List<android.view.View>, android.app.SharedElementCallback.OnSharedElementsReadyListener);
}
public static abstract interface SharedElementCallback.OnSharedElementsReadyListener {
method public abstract void onSharedElementsReady();
}
public deprecated class TabActivity extends android.app.ActivityGroup {

View File

@@ -5401,6 +5401,11 @@ package android.app {
method public void onRejectSharedElements(java.util.List<android.view.View>);
method public void onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
method public void onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
method public void onSharedElementsArrived(java.util.List<java.lang.String>, java.util.List<android.view.View>, android.app.SharedElementCallback.OnSharedElementsReadyListener);
}
public static abstract interface SharedElementCallback.OnSharedElementsReadyListener {
method public abstract void onSharedElementsReady();
}
public deprecated class TabActivity extends android.app.ActivityGroup {

View File

@@ -18,6 +18,7 @@ package android.app;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.SharedElementCallback.OnSharedElementsReadyListener;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.ResultReceiver;
@@ -140,13 +141,13 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
} else {
decor.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
decor.getViewTreeObserver().removeOnPreDrawListener(this);
viewsReady(sharedElements);
return true;
}
});
@Override
public boolean onPreDraw() {
decor.getViewTreeObserver().removeOnPreDrawListener(this);
viewsReady(sharedElements);
return true;
}
});
}
}
@@ -383,23 +384,33 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
}
final Bundle sharedElementState = mSharedElementsBundle;
mSharedElementsBundle = null;
final View decorView = getDecor();
if (decorView != null) {
decorView.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
decorView.getViewTreeObserver().removeOnPreDrawListener(this);
startTransition(new Runnable() {
OnSharedElementsReadyListener listener = new OnSharedElementsReadyListener() {
@Override
public void onSharedElementsReady() {
final View decorView = getDecor();
if (decorView != null) {
decorView.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public void run() {
startSharedElementTransition(sharedElementState);
public boolean onPreDraw() {
decorView.getViewTreeObserver().removeOnPreDrawListener(this);
startTransition(new Runnable() {
@Override
public void run() {
startSharedElementTransition(sharedElementState);
}
});
return false;
}
});
return false;
}
});
decorView.invalidate();
decorView.invalidate();
}
}
};
if (mListener == null) {
listener.onSharedElementsReady();
} else {
mListener.onSharedElementsArrived(mSharedElementNames, mSharedElements, listener);
}
}

View File

@@ -18,6 +18,7 @@ package android.app;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.SharedElementCallback.OnSharedElementsReadyListener;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Matrix;
@@ -27,6 +28,7 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ResultReceiver;
import android.transition.Transition;
import android.transition.TransitionManager;
import android.view.View;
@@ -408,21 +410,41 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
if (!mSharedElementNotified) {
mSharedElementNotified = true;
delayCancel();
mResultReceiver.send(MSG_TAKE_SHARED_ELEMENTS, mSharedElementBundle);
}
if (!mExitNotified && mExitComplete) {
mExitNotified = true;
mResultReceiver.send(MSG_EXIT_TRANSITION_COMPLETE, null);
mResultReceiver = null; // done talking
ViewGroup decorView = getDecor();
if (!mIsReturning && decorView != null) {
decorView.suppressLayout(false);
if (mListener == null) {
mResultReceiver.send(MSG_TAKE_SHARED_ELEMENTS, mSharedElementBundle);
notifyExitComplete();
} else {
final ResultReceiver resultReceiver = mResultReceiver;
final Bundle sharedElementBundle = mSharedElementBundle;
mListener.onSharedElementsArrived(mSharedElementNames, mSharedElements,
new OnSharedElementsReadyListener() {
@Override
public void onSharedElementsReady() {
resultReceiver.send(MSG_TAKE_SHARED_ELEMENTS,
sharedElementBundle);
notifyExitComplete();
}
});
}
finishIfNecessary();
} else {
notifyExitComplete();
}
}
}
private void notifyExitComplete() {
if (!mExitNotified && mExitComplete) {
mExitNotified = true;
mResultReceiver.send(MSG_EXIT_TRANSITION_COMPLETE, null);
mResultReceiver = null; // done talking
ViewGroup decorView = getDecor();
if (!mIsReturning && decorView != null) {
decorView.suppressLayout(false);
}
finishIfNecessary();
}
}
private void finishIfNecessary() {
if (mIsReturning && mExitNotified && mActivity != null && (mSharedElements.isEmpty() ||
mSharedElementsHidden)) {

View File

@@ -221,4 +221,42 @@ public abstract class SharedElementCallback {
}
return view;
}
/**
* Called during an Activity Transition when the shared elements have arrived at the
* final location and are ready to be transferred. This method is called for both the
* source and destination Activities.
* <p>
* When the shared elements are ready to be transferred,
* {@link OnSharedElementsReadyListener#onSharedElementsReady()}
* must be called to trigger the transfer.
* <p>
* The default behavior is to trigger the transfer immediately.
*
* @param sharedElementNames The names of the shared elements that are being transferred..
* @param sharedElements The shared elements that are part of the View hierarchy.
* @param listener The listener to call when the shared elements are ready to be hidden
* in the source Activity or shown in the destination Activity.
*/
public void onSharedElementsArrived(List<String> sharedElementNames,
List<View> sharedElements, OnSharedElementsReadyListener listener) {
listener.onSharedElementsReady();
}
/**
* Listener to be called after {@link
* SharedElementCallback#onSharedElementsArrived(OnSharedElementsReadyListener)}
* when the shared elements are ready to be hidden in the source Activity and shown in the
* destination Activity.
*/
public interface OnSharedElementsReadyListener {
/**
* Call this method during or after the OnSharedElementsReadyListener has been received
* in {@link SharedElementCallback#onSharedElementsArrived(OnSharedElementsReadyListener)}
* to indicate that the shared elements are ready to be hidden in the source and shown
* in the destination Activity.
*/
void onSharedElementsReady();
}
}