Loading core/java/android/app/SharedElementCallback.java +5 −13 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.graphics.Matrix; import android.graphics.RectF; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable; import android.os.Parcelable; import android.os.Parcelable; import android.transition.TransitionUtils; import android.view.View; import android.view.View; import java.util.List; import java.util.List; Loading Loading @@ -141,21 +142,12 @@ public abstract class SharedElementCallback { */ */ public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, RectF screenBounds) { 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) { if (mTempMatrix == null) { mTempMatrix = new Matrix(); mTempMatrix = new Matrix(viewToGlobalMatrix); } } else { mTempMatrix.set(viewToGlobalMatrix); 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; return TransitionUtils.createViewBitmap(sharedElement, mTempMatrix, screenBounds); } } /** /** Loading core/java/android/transition/TransitionUtils.java +72 −0 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,14 @@ package android.transition; import android.animation.Animator; import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.AnimatorSet; import android.animation.TypeEvaluator; import android.animation.TypeEvaluator; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Matrix; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; /** /** * Static utility methods for Transitions. * Static utility methods for Transitions. Loading @@ -27,6 +34,7 @@ import android.graphics.Matrix; * @hide * @hide */ */ public class TransitionUtils { public class TransitionUtils { private static int MAX_IMAGE_SIZE = (1024 * 1024); static Animator mergeAnimators(Animator animator1, Animator animator2) { static Animator mergeAnimators(Animator animator1, Animator animator2) { if (animator1 == null) { if (animator1 == null) { Loading Loading @@ -67,6 +75,70 @@ public class TransitionUtils { return transitionSet; return transitionSet; } } /** * Creates a View using the bitmap copy of <code>view</code>. If <code>view</code> is large, * the copy will use a scaled bitmap of the given view. * * @param sceneRoot The ViewGroup in which the view copy will be displayed. * @param view The view to create a copy of. * @param parent The parent of view. */ public static View copyViewImage(ViewGroup sceneRoot, View view, View parent) { Matrix matrix = new Matrix(); matrix.setTranslate(-parent.getScrollX(), -parent.getScrollY()); view.transformMatrixToGlobal(matrix); sceneRoot.transformMatrixToLocal(matrix); RectF bounds = new RectF(0, 0, view.getWidth(), view.getHeight()); matrix.mapRect(bounds); int left = Math.round(bounds.left); int top = Math.round(bounds.top); int right = Math.round(bounds.right); int bottom = Math.round(bounds.bottom); ImageView copy = new ImageView(view.getContext()); copy.setScaleType(ImageView.ScaleType.CENTER_CROP); Bitmap bitmap = createViewBitmap(view, matrix, bounds); if (bitmap != null) { copy.setImageBitmap(bitmap); } int widthSpec = View.MeasureSpec.makeMeasureSpec(right - left, View.MeasureSpec.EXACTLY); int heightSpec = View.MeasureSpec.makeMeasureSpec(bottom - top, View.MeasureSpec.EXACTLY); copy.measure(widthSpec, heightSpec); copy.layout(left, top, right, bottom); return copy; } /** * Creates a Bitmap of the given view, using the Matrix matrix to transform to the local * coordinates. <code>matrix</code> will be modified during the bitmap creation. * * <p>If the bitmap is large, it will be scaled uniformly down to at most 1MB size.</p> * @param view The view to create a bitmap for. * @param matrix The matrix converting the view local coordinates to the coordinates that * the bitmap will be displayed in. <code>matrix</code> will be modified before * returning. * @param bounds The bounds of the bitmap in the destination coordinate system (where the * view should be presented. Typically, this is matrix.mapRect(viewBounds); * @return A bitmap of the given view or null if bounds has no width or height. */ public static Bitmap createViewBitmap(View view, Matrix matrix, RectF bounds) { Bitmap bitmap = null; int bitmapWidth = Math.round(bounds.width()); int bitmapHeight = Math.round(bounds.height()); if (bitmapWidth > 0 && bitmapHeight > 0) { float scale = Math.min(1f, ((float)MAX_IMAGE_SIZE) / (bitmapWidth * bitmapHeight)); bitmapWidth *= scale; bitmapHeight *= scale; matrix.postTranslate(-bounds.left, -bounds.top); matrix.postScale(scale, scale); bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.concat(matrix); view.draw(canvas); } return bitmap; } public static class MatrixEvaluator implements TypeEvaluator<Matrix> { public static class MatrixEvaluator implements TypeEvaluator<Matrix> { float[] mTempStartValues = new float[9]; float[] mTempStartValues = new float[9]; Loading core/java/android/transition/Visibility.java +8 −31 Original line number Original line Diff line number Diff line Loading @@ -224,11 +224,10 @@ public abstract class Visibility extends Transition { } } } } } } } } else if (startValues == null && visInfo.endVisibility == View.VISIBLE) { if (startValues == null) { visInfo.fadeIn = true; visInfo.fadeIn = true; visInfo.visibilityChange = true; visInfo.visibilityChange = true; } else if (endValues == null) { } else if (endValues == null && visInfo.startVisibility == View.VISIBLE) { visInfo.fadeIn = false; visInfo.fadeIn = false; visInfo.visibilityChange = true; visInfo.visibilityChange = true; } } Loading Loading @@ -370,16 +369,14 @@ public abstract class Visibility extends Transition { overlayView = startView; overlayView = startView; } else if (startView.getParent() instanceof View) { } else if (startView.getParent() instanceof View) { View startParent = (View) startView.getParent(); View startParent = (View) startView.getParent(); VisibilityInfo parentVisibilityInfo = null; TransitionValues startParentValues = getTransitionValues(startParent, true); TransitionValues endParentValues = getMatchedTransitionValues(startParent, TransitionValues endParentValues = getMatchedTransitionValues(startParent, true); true); if (endParentValues != null) { VisibilityInfo parentVisibilityInfo = TransitionValues startParentValues = getTransitionValues(startParent, true); parentVisibilityInfo = getVisibilityChangeInfo(startParentValues, endParentValues); getVisibilityChangeInfo(startParentValues, endParentValues); } if (!parentVisibilityInfo.visibilityChange) { if (parentVisibilityInfo == null || !parentVisibilityInfo.visibilityChange) { overlayView = TransitionUtils.copyViewImage(sceneRoot, startView, overlayView = copyViewImage(startView); startParent); } else if (startParent.getParent() == null) { } else if (startParent.getParent() == null) { int id = startParent.getId(); int id = startParent.getId(); if (id != View.NO_ID && sceneRoot.findViewById(id) != null if (id != View.NO_ID && sceneRoot.findViewById(id) != null Loading Loading @@ -485,26 +482,6 @@ public abstract class Visibility extends Transition { return null; return null; } } private View copyViewImage(View view) { int width = view.getWidth(); int height = view.getHeight(); if (width <= 0 || height <= 0) { return null; } Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.draw(canvas); final BitmapDrawable drawable = new BitmapDrawable(bitmap); View overlayView = new View(view.getContext()); overlayView.setBackground(drawable); int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); overlayView.measure(widthSpec, heightSpec); overlayView.layout(0, 0, width, height); return overlayView; } @Override @Override boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) { boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) { VisibilityInfo changeInfo = getVisibilityChangeInfo(oldValues, newValues); VisibilityInfo changeInfo = getVisibilityChangeInfo(oldValues, newValues); Loading Loading
core/java/android/app/SharedElementCallback.java +5 −13 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.graphics.Matrix; import android.graphics.RectF; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable; import android.os.Parcelable; import android.os.Parcelable; import android.transition.TransitionUtils; import android.view.View; import android.view.View; import java.util.List; import java.util.List; Loading Loading @@ -141,21 +142,12 @@ public abstract class SharedElementCallback { */ */ public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, RectF screenBounds) { 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) { if (mTempMatrix == null) { mTempMatrix = new Matrix(); mTempMatrix = new Matrix(viewToGlobalMatrix); } } else { mTempMatrix.set(viewToGlobalMatrix); 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; return TransitionUtils.createViewBitmap(sharedElement, mTempMatrix, screenBounds); } } /** /** Loading
core/java/android/transition/TransitionUtils.java +72 −0 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,14 @@ package android.transition; import android.animation.Animator; import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.AnimatorSet; import android.animation.TypeEvaluator; import android.animation.TypeEvaluator; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Matrix; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; /** /** * Static utility methods for Transitions. * Static utility methods for Transitions. Loading @@ -27,6 +34,7 @@ import android.graphics.Matrix; * @hide * @hide */ */ public class TransitionUtils { public class TransitionUtils { private static int MAX_IMAGE_SIZE = (1024 * 1024); static Animator mergeAnimators(Animator animator1, Animator animator2) { static Animator mergeAnimators(Animator animator1, Animator animator2) { if (animator1 == null) { if (animator1 == null) { Loading Loading @@ -67,6 +75,70 @@ public class TransitionUtils { return transitionSet; return transitionSet; } } /** * Creates a View using the bitmap copy of <code>view</code>. If <code>view</code> is large, * the copy will use a scaled bitmap of the given view. * * @param sceneRoot The ViewGroup in which the view copy will be displayed. * @param view The view to create a copy of. * @param parent The parent of view. */ public static View copyViewImage(ViewGroup sceneRoot, View view, View parent) { Matrix matrix = new Matrix(); matrix.setTranslate(-parent.getScrollX(), -parent.getScrollY()); view.transformMatrixToGlobal(matrix); sceneRoot.transformMatrixToLocal(matrix); RectF bounds = new RectF(0, 0, view.getWidth(), view.getHeight()); matrix.mapRect(bounds); int left = Math.round(bounds.left); int top = Math.round(bounds.top); int right = Math.round(bounds.right); int bottom = Math.round(bounds.bottom); ImageView copy = new ImageView(view.getContext()); copy.setScaleType(ImageView.ScaleType.CENTER_CROP); Bitmap bitmap = createViewBitmap(view, matrix, bounds); if (bitmap != null) { copy.setImageBitmap(bitmap); } int widthSpec = View.MeasureSpec.makeMeasureSpec(right - left, View.MeasureSpec.EXACTLY); int heightSpec = View.MeasureSpec.makeMeasureSpec(bottom - top, View.MeasureSpec.EXACTLY); copy.measure(widthSpec, heightSpec); copy.layout(left, top, right, bottom); return copy; } /** * Creates a Bitmap of the given view, using the Matrix matrix to transform to the local * coordinates. <code>matrix</code> will be modified during the bitmap creation. * * <p>If the bitmap is large, it will be scaled uniformly down to at most 1MB size.</p> * @param view The view to create a bitmap for. * @param matrix The matrix converting the view local coordinates to the coordinates that * the bitmap will be displayed in. <code>matrix</code> will be modified before * returning. * @param bounds The bounds of the bitmap in the destination coordinate system (where the * view should be presented. Typically, this is matrix.mapRect(viewBounds); * @return A bitmap of the given view or null if bounds has no width or height. */ public static Bitmap createViewBitmap(View view, Matrix matrix, RectF bounds) { Bitmap bitmap = null; int bitmapWidth = Math.round(bounds.width()); int bitmapHeight = Math.round(bounds.height()); if (bitmapWidth > 0 && bitmapHeight > 0) { float scale = Math.min(1f, ((float)MAX_IMAGE_SIZE) / (bitmapWidth * bitmapHeight)); bitmapWidth *= scale; bitmapHeight *= scale; matrix.postTranslate(-bounds.left, -bounds.top); matrix.postScale(scale, scale); bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.concat(matrix); view.draw(canvas); } return bitmap; } public static class MatrixEvaluator implements TypeEvaluator<Matrix> { public static class MatrixEvaluator implements TypeEvaluator<Matrix> { float[] mTempStartValues = new float[9]; float[] mTempStartValues = new float[9]; Loading
core/java/android/transition/Visibility.java +8 −31 Original line number Original line Diff line number Diff line Loading @@ -224,11 +224,10 @@ public abstract class Visibility extends Transition { } } } } } } } } else if (startValues == null && visInfo.endVisibility == View.VISIBLE) { if (startValues == null) { visInfo.fadeIn = true; visInfo.fadeIn = true; visInfo.visibilityChange = true; visInfo.visibilityChange = true; } else if (endValues == null) { } else if (endValues == null && visInfo.startVisibility == View.VISIBLE) { visInfo.fadeIn = false; visInfo.fadeIn = false; visInfo.visibilityChange = true; visInfo.visibilityChange = true; } } Loading Loading @@ -370,16 +369,14 @@ public abstract class Visibility extends Transition { overlayView = startView; overlayView = startView; } else if (startView.getParent() instanceof View) { } else if (startView.getParent() instanceof View) { View startParent = (View) startView.getParent(); View startParent = (View) startView.getParent(); VisibilityInfo parentVisibilityInfo = null; TransitionValues startParentValues = getTransitionValues(startParent, true); TransitionValues endParentValues = getMatchedTransitionValues(startParent, TransitionValues endParentValues = getMatchedTransitionValues(startParent, true); true); if (endParentValues != null) { VisibilityInfo parentVisibilityInfo = TransitionValues startParentValues = getTransitionValues(startParent, true); parentVisibilityInfo = getVisibilityChangeInfo(startParentValues, endParentValues); getVisibilityChangeInfo(startParentValues, endParentValues); } if (!parentVisibilityInfo.visibilityChange) { if (parentVisibilityInfo == null || !parentVisibilityInfo.visibilityChange) { overlayView = TransitionUtils.copyViewImage(sceneRoot, startView, overlayView = copyViewImage(startView); startParent); } else if (startParent.getParent() == null) { } else if (startParent.getParent() == null) { int id = startParent.getId(); int id = startParent.getId(); if (id != View.NO_ID && sceneRoot.findViewById(id) != null if (id != View.NO_ID && sceneRoot.findViewById(id) != null Loading Loading @@ -485,26 +482,6 @@ public abstract class Visibility extends Transition { return null; return null; } } private View copyViewImage(View view) { int width = view.getWidth(); int height = view.getHeight(); if (width <= 0 || height <= 0) { return null; } Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.draw(canvas); final BitmapDrawable drawable = new BitmapDrawable(bitmap); View overlayView = new View(view.getContext()); overlayView.setBackground(drawable); int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); overlayView.measure(widthSpec, heightSpec); overlayView.layout(0, 0, width, height); return overlayView; } @Override @Override boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) { boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) { VisibilityInfo changeInfo = getVisibilityChangeInfo(oldValues, newValues); VisibilityInfo changeInfo = getVisibilityChangeInfo(oldValues, newValues); Loading