diff options
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | core/java/android/app/ActivityTransitionCoordinator.java | 35 | ||||
-rw-r--r-- | core/java/android/app/SharedElementListener.java | 72 |
3 files changed, 89 insertions, 20 deletions
diff --git a/api/current.txt b/api/current.txt index eb991ad..db6ec15 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5148,6 +5148,8 @@ package android.app { public abstract class SharedElementListener { ctor public SharedElementListener(); + method public android.os.Parcelable captureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF); + method public android.view.View createSnapshotView(android.content.Context, android.os.Parcelable); method public void handleRejectedSharedElements(java.util.List<android.view.View>); method public void remapSharedElements(java.util.List<java.lang.String>, java.util.Map<java.lang.String, android.view.View>); method public void setSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>); diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java index a765dd1..039bad0 100644 --- a/core/java/android/app/ActivityTransitionCoordinator.java +++ b/core/java/android/app/ActivityTransitionCoordinator.java @@ -16,15 +16,12 @@ package android.app; import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; -import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.os.Handler; +import android.os.Parcelable; import android.os.ResultReceiver; import android.transition.Transition; import android.transition.TransitionSet; @@ -128,7 +125,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { protected static final String KEY_SCREEN_RIGHT = "shared_element:screenRight"; protected static final String KEY_SCREEN_BOTTOM= "shared_element:screenBottom"; protected static final String KEY_TRANSLATION_Z = "shared_element:translationZ"; - protected static final String KEY_BITMAP = "shared_element:bitmap"; + protected static final String KEY_SNAPSHOT = "shared_element:bitmap"; protected static final String KEY_SCALE_TYPE = "shared_element:scaleType"; protected static final String KEY_IMAGE_MATRIX = "shared_element:imageMatrix"; @@ -405,6 +402,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { if (decorLoc != null) { left -= decorLoc[0]; top -= decorLoc[1]; + right -= decorLoc[0]; + bottom -= decorLoc[1]; } else { // Find the location in the view's parent getSharedElementParentMatrix(view, tempMatrix); @@ -532,14 +531,14 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { for (String name: names) { Bundle sharedElementBundle = state.getBundle(name); if (sharedElementBundle != null) { - Bitmap bitmap = sharedElementBundle.getParcelable(KEY_BITMAP); - View snapshot = new View(context); - Resources resources = getWindow().getContext().getResources(); - if (bitmap != null) { - snapshot.setBackground(new BitmapDrawable(resources, bitmap)); + Parcelable parcelable = sharedElementBundle.getParcelable(KEY_SNAPSHOT); + View snapshot = null; + if (parcelable != null) { + snapshot = mListener.createSnapshotView(context, parcelable); + } + if (snapshot != null) { + setSharedElementState(snapshot, name, state, null, null, decorLoc); } - snapshot.setTransitionName(name); - setSharedElementState(snapshot, name, state, null, null, decorLoc); snapshots.add(snapshot); } } @@ -610,7 +609,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { * @param transitionArgs Bundle to store shared element placement information. * @param tempBounds A temporary Rect for capturing the current location of views. */ - protected static void captureSharedElementState(View view, String name, Bundle transitionArgs, + protected void captureSharedElementState(View view, String name, Bundle transitionArgs, Matrix tempMatrix, RectF tempBounds) { Bundle sharedElementBundle = new Bundle(); tempMatrix.reset(); @@ -624,13 +623,9 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { sharedElementBundle.putFloat(KEY_SCREEN_BOTTOM, tempBounds.bottom); sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ()); - int bitmapWidth = Math.round(tempBounds.width()); - int bitmapHeight = Math.round(tempBounds.height()); - if (bitmapWidth > 0 && bitmapHeight > 0) { - Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapWidth, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - view.draw(canvas); - sharedElementBundle.putParcelable(KEY_BITMAP, bitmap); + Parcelable bitmap = mListener.captureSharedElementSnapshot(view, tempMatrix, tempBounds); + if (bitmap != null) { + sharedElementBundle.putParcelable(KEY_SNAPSHOT, bitmap); } if (view instanceof ImageView) { diff --git a/core/java/android/app/SharedElementListener.java b/core/java/android/app/SharedElementListener.java index 14fbfab..f36d05f 100644 --- a/core/java/android/app/SharedElementListener.java +++ b/core/java/android/app/SharedElementListener.java @@ -15,6 +15,15 @@ */ package android.app; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.RectF; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; +import android.os.Parcelable; import android.view.View; import java.util.List; @@ -28,6 +37,7 @@ import java.util.Map; * Transition behavior. */ public abstract class SharedElementListener { + private Matrix mTempMatrix; static final SharedElementListener NULL_LISTENER = new SharedElementListener() { }; @@ -111,4 +121,66 @@ public abstract class SharedElementListener { * will be filled into sharedElements based on the transitionNames. */ public void remapSharedElements(List<String> names, Map<String, View> sharedElements) {} + + /** + * Creates a snapshot of a shared element to be used by the remote Activity and reconstituted + * with {@link #createSnapshotView(android.content.Context, android.os.Parcelable)}. A + * null return value will mean that the remote Activity will have a null snapshot View in + * {@link #setSharedElementStart(java.util.List, java.util.List, java.util.List)} and + * {@link #setSharedElementEnd(java.util.List, java.util.List, java.util.List)}. + * + * @param sharedElement The shared element View to create a snapshot for. + * @param viewToGlobalMatrix A matrix containing a transform from the view to the screen + * coordinates. + * @param screenBounds The bounds of shared element in screen coordinate space. This is + * the bounds of the view with the viewToGlobalMatrix applied. + * @return A snapshot to send to the remote Activity to be reconstituted with + * {@link #createSnapshotView(android.content.Context, android.os.Parcelable)} and passed + * into {@link #setSharedElementStart(java.util.List, java.util.List, java.util.List)} and + * {@link #setSharedElementEnd(java.util.List, java.util.List, java.util.List)}. + */ + public Parcelable captureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, + RectF screenBounds) { + int bitmapWidth = Math.round(screenBounds.width()); + int bitmapHeight = Math.round(screenBounds.height()); + Bitmap bitmap = null; + if (bitmapWidth > 0 && bitmapHeight > 0) { + if (mTempMatrix == null) { + mTempMatrix = new Matrix(); + } + mTempMatrix.set(viewToGlobalMatrix); + mTempMatrix.postTranslate(-screenBounds.left, -screenBounds.top); + bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + canvas.concat(mTempMatrix); + sharedElement.draw(canvas); + } + return bitmap; + } + + /** + * Reconstitutes a snapshot View from a Parcelable returned in + * {@link #captureSharedElementSnapshot(android.view.View, android.graphics.Matrix, + * android.graphics.RectF)} to be used in {@link #setSharedElementStart(java.util.List, + * java.util.List, java.util.List)} and {@link #setSharedElementEnd(java.util.List, + * java.util.List, java.util.List)}. The returned View will be sized and positioned after + * this call so that it is ready to be added to the decor View's overlay. + * + * @param context The Context used to create the snapshot View. + * @param snapshot The Parcelable returned by {@link #captureSharedElementSnapshot( + * android.view.View, android.graphics.Matrix, android.graphics.RectF)}. + * @return A View to be sent in {@link #setSharedElementStart(java.util.List, java.util.List, + * java.util.List)} and {@link #setSharedElementEnd(java.util.List, java.util.List, + * java.util.List)}. A null value will produce a null snapshot value for those two methods. + */ + public View createSnapshotView(Context context, Parcelable snapshot) { + View view = null; + if (snapshot instanceof Bitmap) { + Bitmap bitmap = (Bitmap) snapshot; + view = new View(context); + Resources resources = context.getResources(); + view.setBackground(new BitmapDrawable(resources, bitmap)); + } + return view; + } } |