1fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki/* 2fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * Copyright (C) 2017 The Android Open Source Project 3fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * 4fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * Licensed under the Apache License, Version 2.0 (the "License"); 5fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * you may not use this file except in compliance with the License. 6fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * You may obtain a copy of the License at 7fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * 8fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * http://www.apache.org/licenses/LICENSE-2.0 9fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * 10fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * Unless required by applicable law or agreed to in writing, software 11fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * distributed under the License is distributed on an "AS IS" BASIS, 12fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * See the License for the specific language governing permissions and 14fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki * limitations under the License. 15fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki */ 16fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.transition; 18fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 19fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport static org.junit.Assert.assertEquals; 20fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport static org.junit.Assert.assertNotNull; 21fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport static org.junit.Assert.assertNull; 22fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport static org.mockito.Matchers.any; 23fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport static org.mockito.Mockito.never; 24fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport static org.mockito.Mockito.times; 25fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport static org.mockito.Mockito.verify; 26fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 27fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.animation.Animator; 28fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.animation.AnimatorListenerAdapter; 29fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.graphics.Matrix; 30fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.graphics.drawable.Drawable; 31fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.support.test.InstrumentationRegistry; 32fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.support.test.filters.MediumTest; 33fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.util.DisplayMetrics; 34fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.util.TypedValue; 35fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.view.ViewGroup; 36fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport android.widget.ImageView; 37fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 384d1d6a17310a57807dabb3f404715cfe43a90ed0Aurimas Liutikasimport androidx.annotation.NonNull; 394d1d6a17310a57807dabb3f404715cfe43a90ed0Aurimas Liutikasimport androidx.core.app.ActivityCompat; 404d1d6a17310a57807dabb3f404715cfe43a90ed0Aurimas Liutikasimport androidx.transition.test.R; 414d1d6a17310a57807dabb3f404715cfe43a90ed0Aurimas Liutikas 42fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakiimport org.junit.Test; 43fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 44fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki@MediumTest 45fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Arakipublic class ChangeImageTransformTest extends BaseTransitionTest { 46fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 47fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private ChangeImageTransform mChangeImageTransform; 48fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix mStartMatrix; 49fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix mEndMatrix; 50fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Drawable mImage; 51fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private ImageView mImageView; 52fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 53fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Override 54fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Transition createTransition() { 55fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mChangeImageTransform = new CaptureMatrix(); 56fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mChangeImageTransform.setDuration(100); 57fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mTransition = mChangeImageTransform; 58fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki resetListener(); 59fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return mChangeImageTransform; 60fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 61fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 62fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Test 63fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public void testCenterToFitXY() throws Throwable { 64fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki transformImage(ImageView.ScaleType.CENTER, ImageView.ScaleType.FIT_XY); 65fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verifyMatrixMatches(centerMatrix(), mStartMatrix); 66fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verifyMatrixMatches(fitXYMatrix(), mEndMatrix); 67fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 68fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 69fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Test 70fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public void testCenterCropToFitCenter() throws Throwable { 71fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki transformImage(ImageView.ScaleType.CENTER_CROP, ImageView.ScaleType.FIT_CENTER); 72fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verifyMatrixMatches(centerCropMatrix(), mStartMatrix); 73fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verifyMatrixMatches(fitCenterMatrix(), mEndMatrix); 74fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 75fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 76fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Test 77fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public void testCenterInsideToFitEnd() throws Throwable { 78fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki transformImage(ImageView.ScaleType.CENTER_INSIDE, ImageView.ScaleType.FIT_END); 79fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki // CENTER_INSIDE and CENTER are the same when the image is smaller than the View 80fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verifyMatrixMatches(centerMatrix(), mStartMatrix); 81fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verifyMatrixMatches(fitEndMatrix(), mEndMatrix); 82fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 83fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 84fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Test 85fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public void testFitStartToCenter() throws Throwable { 86fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki transformImage(ImageView.ScaleType.FIT_START, ImageView.ScaleType.CENTER); 87fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verifyMatrixMatches(fitStartMatrix(), mStartMatrix); 88fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verifyMatrixMatches(centerMatrix(), mEndMatrix); 89fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 90fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 91fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix centerMatrix() { 92fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageWidth = mImage.getIntrinsicWidth(); 93fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewWidth = mImageView.getWidth(); 94fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float tx = Math.round((imageViewWidth - imageWidth) / 2f); 95fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 96fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageHeight = mImage.getIntrinsicHeight(); 97fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewHeight = mImageView.getHeight(); 98fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float ty = Math.round((imageViewHeight - imageHeight) / 2f); 99fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 100fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Matrix matrix = new Matrix(); 101fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postTranslate(tx, ty); 102fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return matrix; 103fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 104fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 105fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix fitXYMatrix() { 106fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageWidth = mImage.getIntrinsicWidth(); 107fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewWidth = mImageView.getWidth(); 108fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleX = ((float) imageViewWidth) / imageWidth; 109fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 110fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageHeight = mImage.getIntrinsicHeight(); 111fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewHeight = mImageView.getHeight(); 112fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleY = ((float) imageViewHeight) / imageHeight; 113fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 114fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Matrix matrix = new Matrix(); 115fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postScale(scaleX, scaleY); 116fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return matrix; 117fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 118fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 119fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix centerCropMatrix() { 120fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageWidth = mImage.getIntrinsicWidth(); 121fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewWidth = mImageView.getWidth(); 122fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleX = ((float) imageViewWidth) / imageWidth; 123fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 124fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageHeight = mImage.getIntrinsicHeight(); 125fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewHeight = mImageView.getHeight(); 126fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleY = ((float) imageViewHeight) / imageHeight; 127fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 128fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float maxScale = Math.max(scaleX, scaleY); 129fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 130fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float width = imageWidth * maxScale; 131fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float height = imageHeight * maxScale; 132fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int tx = Math.round((imageViewWidth - width) / 2f); 133fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int ty = Math.round((imageViewHeight - height) / 2f); 134fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 135fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Matrix matrix = new Matrix(); 136fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postScale(maxScale, maxScale); 137fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postTranslate(tx, ty); 138fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return matrix; 139fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 140fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 141fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix fitCenterMatrix() { 142fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageWidth = mImage.getIntrinsicWidth(); 143fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewWidth = mImageView.getWidth(); 144fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleX = ((float) imageViewWidth) / imageWidth; 145fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 146fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageHeight = mImage.getIntrinsicHeight(); 147fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewHeight = mImageView.getHeight(); 148fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleY = ((float) imageViewHeight) / imageHeight; 149fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 150fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float minScale = Math.min(scaleX, scaleY); 151fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 152fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float width = imageWidth * minScale; 153fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float height = imageHeight * minScale; 154fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float tx = (imageViewWidth - width) / 2f; 155fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float ty = (imageViewHeight - height) / 2f; 156fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 157fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Matrix matrix = new Matrix(); 158fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postScale(minScale, minScale); 159fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postTranslate(tx, ty); 160fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return matrix; 161fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 162fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 163fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix fitStartMatrix() { 164fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageWidth = mImage.getIntrinsicWidth(); 165fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewWidth = mImageView.getWidth(); 166fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleX = ((float) imageViewWidth) / imageWidth; 167fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 168fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageHeight = mImage.getIntrinsicHeight(); 169fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewHeight = mImageView.getHeight(); 170fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleY = ((float) imageViewHeight) / imageHeight; 171fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 172fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float minScale = Math.min(scaleX, scaleY); 173fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 174fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Matrix matrix = new Matrix(); 175fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postScale(minScale, minScale); 176fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return matrix; 177fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 178fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 179fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix fitEndMatrix() { 180fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageWidth = mImage.getIntrinsicWidth(); 181fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewWidth = mImageView.getWidth(); 182fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleX = ((float) imageViewWidth) / imageWidth; 183fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 184fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageHeight = mImage.getIntrinsicHeight(); 185fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki int imageViewHeight = mImageView.getHeight(); 186fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float scaleY = ((float) imageViewHeight) / imageHeight; 187fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 188fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float minScale = Math.min(scaleX, scaleY); 189fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 190fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float width = imageWidth * minScale; 191fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float height = imageHeight * minScale; 192fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float tx = imageViewWidth - width; 193fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float ty = imageViewHeight - height; 194fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 195fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Matrix matrix = new Matrix(); 196fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postScale(minScale, minScale); 197fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.postTranslate(tx, ty); 198fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return matrix; 199fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 200fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 201fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private void verifyMatrixMatches(Matrix expected, Matrix matrix) { 202fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki if (expected == null) { 203fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki assertNull(matrix); 204fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return; 205fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 206fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki assertNotNull(matrix); 207fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float[] expectedValues = new float[9]; 208fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki expected.getValues(expectedValues); 209fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 210fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float[] values = new float[9]; 211fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix.getValues(values); 212fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 213fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki for (int i = 0; i < values.length; i++) { 214fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki final float expectedValue = expectedValues[i]; 215fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki final float value = values[i]; 216fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki assertEquals("Value [" + i + "]", expectedValue, value, 0.01f); 217fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 218fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 219fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 220fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private void transformImage(ImageView.ScaleType startScale, final ImageView.ScaleType endScale) 221fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki throws Throwable { 222fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki final ImageView imageView = enterImageViewScene(startScale); 223fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki rule.runOnUiThread(new Runnable() { 224fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Override 225fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public void run() { 226fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki TransitionManager.beginDelayedTransition(mRoot, mChangeImageTransform); 227fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki imageView.setScaleType(endScale); 228fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 229fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki }); 230fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki waitForStart(); 231fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki verify(mListener, (startScale == endScale) ? times(1) : never()) 232fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki .onTransitionEnd(any(Transition.class)); 233fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki waitForEnd(); 234fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 235fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 236fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private ImageView enterImageViewScene(final ImageView.ScaleType scaleType) throws Throwable { 237fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki enterScene(R.layout.scene4); 238fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki final ViewGroup container = (ViewGroup) rule.getActivity().findViewById(R.id.holder); 239fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki final ImageView[] imageViews = new ImageView[1]; 240fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki rule.runOnUiThread(new Runnable() { 241fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Override 242fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public void run() { 243fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mImageView = new ImageView(rule.getActivity()); 244fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mImage = ActivityCompat.getDrawable(rule.getActivity(), 245fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki android.R.drawable.ic_media_play); 246fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mImageView.setImageDrawable(mImage); 247fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mImageView.setScaleType(scaleType); 248fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki imageViews[0] = mImageView; 249fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki container.addView(mImageView); 250fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki ViewGroup.LayoutParams layoutParams = mImageView.getLayoutParams(); 251fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki DisplayMetrics metrics = rule.getActivity().getResources().getDisplayMetrics(); 252fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki float size = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, metrics); 253fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki layoutParams.width = Math.round(size); 254fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki layoutParams.height = Math.round(size * 2); 255fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mImageView.setLayoutParams(layoutParams); 256fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 257fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki }); 258fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki InstrumentationRegistry.getInstrumentation().waitForIdleSync(); 259fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return imageViews[0]; 260fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 261fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 262fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private class CaptureMatrix extends ChangeImageTransform { 263fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 264fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Override 265fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public Animator createAnimator(@NonNull ViewGroup sceneRoot, TransitionValues startValues, 266fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki TransitionValues endValues) { 267fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Animator animator = super.createAnimator(sceneRoot, startValues, endValues); 268fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki assertNotNull(animator); 269fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki animator.addListener(new CaptureMatrixListener((ImageView) endValues.view)); 270fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return animator; 271fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 272fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 273fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 274fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 275fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private class CaptureMatrixListener extends AnimatorListenerAdapter { 276fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 277fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private final ImageView mImageView; 278fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 279fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki CaptureMatrixListener(ImageView view) { 280fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mImageView = view; 281fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 282fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 283fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Override 284fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public void onAnimationStart(Animator animation) { 285fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mStartMatrix = copyMatrix(); 286fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 287fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 288fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki @Override 289fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki public void onAnimationEnd(Animator animation) { 290fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki mEndMatrix = copyMatrix(); 291fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 292fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 293fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki private Matrix copyMatrix() { 294fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki Matrix matrix = mImageView.getImageMatrix(); 295fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki if (matrix != null) { 296fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki matrix = new Matrix(matrix); 297fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 298fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki return matrix; 299fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 300fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 301fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki } 302fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki 303fdfa819aa29e12734eb90101f5f40d2636a5f1aeYuichi Araki} 304