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