diff options
author | Justin Klaassen <justinklaassen@google.com> | 2017-09-15 17:58:39 -0400 |
---|---|---|
committer | Justin Klaassen <justinklaassen@google.com> | 2017-09-15 17:58:39 -0400 |
commit | 10d07c88d69cc64f73a069163e7ea5ba2519a099 (patch) | |
tree | 8dbd149eb350320a29c3d10e7ad3201de1c5cbee /android/transition/ChangeImageTransform.java | |
parent | 677516fb6b6f207d373984757d3d9450474b6b00 (diff) | |
download | android-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.java | 200 |
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); + } +} |