summaryrefslogtreecommitdiff
path: root/android/transition/ChangeImageTransform.java
diff options
context:
space:
mode:
authorJustin Klaassen <justinklaassen@google.com>2017-09-15 17:58:39 -0400
committerJustin Klaassen <justinklaassen@google.com>2017-09-15 17:58:39 -0400
commit10d07c88d69cc64f73a069163e7ea5ba2519a099 (patch)
tree8dbd149eb350320a29c3d10e7ad3201de1c5cbee /android/transition/ChangeImageTransform.java
parent677516fb6b6f207d373984757d3d9450474b6b00 (diff)
downloadandroid-28-10d07c88d69cc64f73a069163e7ea5ba2519a099.tar.gz
Import Android SDK Platform PI [4335822]
/google/data/ro/projects/android/fetch_artifact \ --bid 4335822 \ --target sdk_phone_armv7-win_sdk \ sdk-repo-linux-sources-4335822.zip AndroidVersion.ApiLevel has been modified to appear as 28 Change-Id: Ic8f04be005a71c2b9abeaac754d8da8d6f9a2c32
Diffstat (limited to 'android/transition/ChangeImageTransform.java')
-rw-r--r--android/transition/ChangeImageTransform.java200
1 files changed, 200 insertions, 0 deletions
diff --git a/android/transition/ChangeImageTransform.java b/android/transition/ChangeImageTransform.java
new file mode 100644
index 00000000..d7a91205
--- /dev/null
+++ b/android/transition/ChangeImageTransform.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.transition;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.TypeEvaluator;
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Property;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import java.util.Map;
+
+/**
+ * This Transition captures an ImageView's matrix before and after the
+ * scene change and animates it during the transition.
+ *
+ * <p>In combination with ChangeBounds, ChangeImageTransform allows ImageViews
+ * that change size, shape, or {@link android.widget.ImageView.ScaleType} to animate contents
+ * smoothly.</p>
+ */
+public class ChangeImageTransform extends Transition {
+
+ private static final String TAG = "ChangeImageTransform";
+
+ private static final String PROPNAME_MATRIX = "android:changeImageTransform:matrix";
+ private static final String PROPNAME_BOUNDS = "android:changeImageTransform:bounds";
+
+ private static final String[] sTransitionProperties = {
+ PROPNAME_MATRIX,
+ PROPNAME_BOUNDS,
+ };
+
+ private static TypeEvaluator<Matrix> NULL_MATRIX_EVALUATOR = new TypeEvaluator<Matrix>() {
+ @Override
+ public Matrix evaluate(float fraction, Matrix startValue, Matrix endValue) {
+ return null;
+ }
+ };
+
+ private static Property<ImageView, Matrix> ANIMATED_TRANSFORM_PROPERTY
+ = new Property<ImageView, Matrix>(Matrix.class, "animatedTransform") {
+ @Override
+ public void set(ImageView object, Matrix value) {
+ object.animateTransform(value);
+ }
+
+ @Override
+ public Matrix get(ImageView object) {
+ return null;
+ }
+ };
+
+ public ChangeImageTransform() {}
+
+ public ChangeImageTransform(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ private void captureValues(TransitionValues transitionValues) {
+ View view = transitionValues.view;
+ if (!(view instanceof ImageView) || view.getVisibility() != View.VISIBLE) {
+ return;
+ }
+ ImageView imageView = (ImageView) view;
+ Drawable drawable = imageView.getDrawable();
+ if (drawable == null) {
+ return;
+ }
+ Map<String, Object> values = transitionValues.values;
+
+ int left = view.getLeft();
+ int top = view.getTop();
+ int right = view.getRight();
+ int bottom = view.getBottom();
+
+ Rect bounds = new Rect(left, top, right, bottom);
+ values.put(PROPNAME_BOUNDS, bounds);
+ Matrix matrix;
+ ImageView.ScaleType scaleType = imageView.getScaleType();
+ if (scaleType == ImageView.ScaleType.FIT_XY) {
+ matrix = imageView.getImageMatrix();
+ if (!matrix.isIdentity()) {
+ matrix = new Matrix(matrix);
+ } else {
+ int drawableWidth = drawable.getIntrinsicWidth();
+ int drawableHeight = drawable.getIntrinsicHeight();
+ if (drawableWidth > 0 && drawableHeight > 0) {
+ float scaleX = ((float) bounds.width()) / drawableWidth;
+ float scaleY = ((float) bounds.height()) / drawableHeight;
+ matrix = new Matrix();
+ matrix.setScale(scaleX, scaleY);
+ } else {
+ matrix = null;
+ }
+ }
+ } else {
+ matrix = new Matrix(imageView.getImageMatrix());
+ }
+ values.put(PROPNAME_MATRIX, matrix);
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public String[] getTransitionProperties() {
+ return sTransitionProperties;
+ }
+
+ /**
+ * Creates an Animator for ImageViews moving, changing dimensions, and/or changing
+ * {@link android.widget.ImageView.ScaleType}.
+ *
+ * @param sceneRoot The root of the transition hierarchy.
+ * @param startValues The values for a specific target in the start scene.
+ * @param endValues The values for the target in the end scene.
+ * @return An Animator to move an ImageView or null if the View is not an ImageView,
+ * the Drawable changed, the View is not VISIBLE, or there was no change.
+ */
+ @Override
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
+ Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
+ Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
+ if (startBounds == null || endBounds == null) {
+ return null;
+ }
+
+ Matrix startMatrix = (Matrix) startValues.values.get(PROPNAME_MATRIX);
+ Matrix endMatrix = (Matrix) endValues.values.get(PROPNAME_MATRIX);
+
+ boolean matricesEqual = (startMatrix == null && endMatrix == null) ||
+ (startMatrix != null && startMatrix.equals(endMatrix));
+
+ if (startBounds.equals(endBounds) && matricesEqual) {
+ return null;
+ }
+
+ ImageView imageView = (ImageView) endValues.view;
+ Drawable drawable = imageView.getDrawable();
+ int drawableWidth = drawable.getIntrinsicWidth();
+ int drawableHeight = drawable.getIntrinsicHeight();
+
+ ObjectAnimator animator;
+ if (drawableWidth == 0 || drawableHeight == 0) {
+ animator = createNullAnimator(imageView);
+ } else {
+ if (startMatrix == null) {
+ startMatrix = Matrix.IDENTITY_MATRIX;
+ }
+ if (endMatrix == null) {
+ endMatrix = Matrix.IDENTITY_MATRIX;
+ }
+ ANIMATED_TRANSFORM_PROPERTY.set(imageView, startMatrix);
+ animator = createMatrixAnimator(imageView, startMatrix, endMatrix);
+ }
+ return animator;
+ }
+
+ private ObjectAnimator createNullAnimator(ImageView imageView) {
+ return ObjectAnimator.ofObject(imageView, ANIMATED_TRANSFORM_PROPERTY,
+ NULL_MATRIX_EVALUATOR, null, null);
+ }
+
+ private ObjectAnimator createMatrixAnimator(final ImageView imageView, Matrix startMatrix,
+ final Matrix endMatrix) {
+ return ObjectAnimator.ofObject(imageView, ANIMATED_TRANSFORM_PROPERTY,
+ new TransitionUtils.MatrixEvaluator(), startMatrix, endMatrix);
+ }
+}