19306f07b1d66f4974a81f781d29739b30124fff0George Mount/* 29306f07b1d66f4974a81f781d29739b30124fff0George Mount * Copyright (C) 2014 The Android Open Source Project 39306f07b1d66f4974a81f781d29739b30124fff0George Mount * 49306f07b1d66f4974a81f781d29739b30124fff0George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 59306f07b1d66f4974a81f781d29739b30124fff0George Mount * you may not use this file except in compliance with the License. 69306f07b1d66f4974a81f781d29739b30124fff0George Mount * You may obtain a copy of the License at 79306f07b1d66f4974a81f781d29739b30124fff0George Mount * 89306f07b1d66f4974a81f781d29739b30124fff0George Mount * http://www.apache.org/licenses/LICENSE-2.0 99306f07b1d66f4974a81f781d29739b30124fff0George Mount * 109306f07b1d66f4974a81f781d29739b30124fff0George Mount * Unless required by applicable law or agreed to in writing, software 119306f07b1d66f4974a81f781d29739b30124fff0George Mount * distributed under the License is distributed on an "AS IS" BASIS, 129306f07b1d66f4974a81f781d29739b30124fff0George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139306f07b1d66f4974a81f781d29739b30124fff0George Mount * See the License for the specific language governing permissions and 149306f07b1d66f4974a81f781d29739b30124fff0George Mount * limitations under the License. 159306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 169306f07b1d66f4974a81f781d29739b30124fff0George Mountpackage android.support.v4.app; 179306f07b1d66f4974a81f781d29739b30124fff0George Mount 189306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.content.Context; 199306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.content.res.Resources; 209306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.Bitmap; 219306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.Canvas; 229306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.Matrix; 23b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.graphics.Rect; 249306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.RectF; 259306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.drawable.BitmapDrawable; 26b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.graphics.drawable.Drawable; 27b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.os.Bundle; 289306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.os.Parcelable; 299306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.view.View; 309306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.widget.ImageView; 31b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.widget.ImageView.ScaleType; 329306f07b1d66f4974a81f781d29739b30124fff0George Mount 339306f07b1d66f4974a81f781d29739b30124fff0George Mountimport java.util.List; 349306f07b1d66f4974a81f781d29739b30124fff0George Mountimport java.util.Map; 359306f07b1d66f4974a81f781d29739b30124fff0George Mount 369306f07b1d66f4974a81f781d29739b30124fff0George Mount/** 379306f07b1d66f4974a81f781d29739b30124fff0George Mount * Listener provided in 389306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link FragmentActivity#setEnterSharedElementCallback(SharedElementCallback)} and 399306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link FragmentActivity#setExitSharedElementCallback(SharedElementCallback)} 409306f07b1d66f4974a81f781d29739b30124fff0George Mount * to monitor the Activity transitions. The events can be used to customize Activity 419306f07b1d66f4974a81f781d29739b30124fff0George Mount * Transition behavior. 429306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 439306f07b1d66f4974a81f781d29739b30124fff0George Mountpublic abstract class SharedElementCallback { 449306f07b1d66f4974a81f781d29739b30124fff0George Mount private Matrix mTempMatrix; 45b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static int MAX_IMAGE_SIZE = (1024 * 1024); 46b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static final String BUNDLE_SNAPSHOT_BITMAP = "sharedElement:snapshot:bitmap"; 47b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static final String BUNDLE_SNAPSHOT_IMAGE_SCALETYPE = "sharedElement:snapshot:imageScaleType"; 48b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static final String BUNDLE_SNAPSHOT_IMAGE_MATRIX = "sharedElement:snapshot:imageMatrix"; 499306f07b1d66f4974a81f781d29739b30124fff0George Mount 509306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 510094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * In Activity Transitions, onSharedElementStart is called immediately before 520094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * capturing the start of the shared element state on enter and reenter transitions and 530094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * immediately before capturing the end of the shared element state for exit and return 540094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * transitions. 550094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 560094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * In Fragment Transitions, onSharedElementStart is called immediately before capturing the 570094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * start state of all shared element transitions. 580094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 590094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * This call can be used to adjust the transition start state by modifying the shared 600094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * element Views. Note that no layout step will be executed between onSharedElementStart 610094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * and the transition state capture. 620094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 630094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * For Activity Transitions, any changes made in {@link #onSharedElementEnd(List, List, List)} 640094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * that are not updated during layout should be corrected in onSharedElementStart for exit and 650094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * return transitions. For example, rotation or scale will not be affected by layout and 660094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * if changed in {@link #onSharedElementEnd(List, List, List)}, it will also have to be reset 670094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * in onSharedElementStart again to correct the end state. 689306f07b1d66f4974a81f781d29739b30124fff0George Mount * 699306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElementNames The names of the shared elements that were accepted into 709306f07b1d66f4974a81f781d29739b30124fff0George Mount * the View hierarchy. 719306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElements The shared elements that are part of the View hierarchy. 729306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElementSnapshots The Views containing snap shots of the shared element 739306f07b1d66f4974a81f781d29739b30124fff0George Mount * from the launching Window. These elements will not 749306f07b1d66f4974a81f781d29739b30124fff0George Mount * be part of the scene, but will be positioned relative 759306f07b1d66f4974a81f781d29739b30124fff0George Mount * to the Window decor View. This list is null for Fragment 769306f07b1d66f4974a81f781d29739b30124fff0George Mount * Transitions. 779306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 789306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onSharedElementStart(List<String> sharedElementNames, 799306f07b1d66f4974a81f781d29739b30124fff0George Mount List<View> sharedElements, List<View> sharedElementSnapshots) {} 809306f07b1d66f4974a81f781d29739b30124fff0George Mount 819306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 820094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * In Activity Transitions, onSharedElementEnd is called immediately before 830094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * capturing the end of the shared element state on enter and reenter transitions and 840094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * immediately before capturing the start of the shared element state for exit and return 850094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * transitions. 860094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 870094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * In Fragment Transitions, onSharedElementEnd is called immediately before capturing the 880094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * end state of all shared element transitions. 890094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 900094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * This call can be used to adjust the transition end state by modifying the shared 910094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * element Views. Note that no layout step will be executed between onSharedElementEnd 920094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * and the transition state capture. 939306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p> 940094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * Any changes made in {@link #onSharedElementStart(List, List, List)} that are not updated 950094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * during layout should be corrected in onSharedElementEnd. For example, rotation or scale 960094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * will not be affected by layout and if changed in 970094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * {@link #onSharedElementStart(List, List, List)}, it will also have to be reset in 980094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * onSharedElementEnd again to correct the end state. 999306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1009306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElementNames The names of the shared elements that were accepted into 1019306f07b1d66f4974a81f781d29739b30124fff0George Mount * the View hierarchy. 1029306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElements The shared elements that are part of the View hierarchy. 1039306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElementSnapshots The Views containing snap shots of the shared element 1049306f07b1d66f4974a81f781d29739b30124fff0George Mount * from the launching Window. These elements will not 1059306f07b1d66f4974a81f781d29739b30124fff0George Mount * be part of the scene, but will be positioned relative 1069306f07b1d66f4974a81f781d29739b30124fff0George Mount * to the Window decor View. This list will be null for 1079306f07b1d66f4974a81f781d29739b30124fff0George Mount * Fragment Transitions. 1089306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 1099306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onSharedElementEnd(List<String> sharedElementNames, 1109306f07b1d66f4974a81f781d29739b30124fff0George Mount List<View> sharedElements, List<View> sharedElementSnapshots) {} 1119306f07b1d66f4974a81f781d29739b30124fff0George Mount 1129306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 1139306f07b1d66f4974a81f781d29739b30124fff0George Mount * Called after {@link #onMapSharedElements(java.util.List, java.util.Map)} when 1149306f07b1d66f4974a81f781d29739b30124fff0George Mount * transferring shared elements in. Any shared elements that have no mapping will be in 1159306f07b1d66f4974a81f781d29739b30124fff0George Mount * <var>rejectedSharedElements</var>. The elements remaining in 1169306f07b1d66f4974a81f781d29739b30124fff0George Mount * <var>rejectedSharedElements</var> will be transitioned out of the Scene. If a 1179306f07b1d66f4974a81f781d29739b30124fff0George Mount * View is removed from <var>rejectedSharedElements</var>, it must be handled by the 1189306f07b1d66f4974a81f781d29739b30124fff0George Mount * <code>SharedElementListener</code>. 1199306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p> 1209306f07b1d66f4974a81f781d29739b30124fff0George Mount * Views in rejectedSharedElements will have their position and size set to the 1219306f07b1d66f4974a81f781d29739b30124fff0George Mount * position of the calling shared element, relative to the Window decor View and contain 1229306f07b1d66f4974a81f781d29739b30124fff0George Mount * snapshots of the View from the calling Activity or Fragment. This 1239306f07b1d66f4974a81f781d29739b30124fff0George Mount * view may be safely added to the decor View's overlay to remain in position. 1249306f07b1d66f4974a81f781d29739b30124fff0George Mount * </p> 1259306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p>This method is not called for Fragment Transitions. All rejected shared elements 1269306f07b1d66f4974a81f781d29739b30124fff0George Mount * will be handled by the exit transition.</p> 1279306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1289306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param rejectedSharedElements Views containing visual information of shared elements 1299306f07b1d66f4974a81f781d29739b30124fff0George Mount * that are not part of the entering scene. These Views 1309306f07b1d66f4974a81f781d29739b30124fff0George Mount * are positioned relative to the Window decor View. A 1319306f07b1d66f4974a81f781d29739b30124fff0George Mount * View removed from this list will not be transitioned 1329306f07b1d66f4974a81f781d29739b30124fff0George Mount * automatically. 1339306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 1349306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onRejectSharedElements(List<View> rejectedSharedElements) {} 1359306f07b1d66f4974a81f781d29739b30124fff0George Mount 1369306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 1379306f07b1d66f4974a81f781d29739b30124fff0George Mount * Lets the SharedElementCallback adjust the mapping of shared element names to 1389306f07b1d66f4974a81f781d29739b30124fff0George Mount * Views. 1399306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1409306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param names The names of all shared elements transferred from the calling Activity 1419306f07b1d66f4974a81f781d29739b30124fff0George Mount * or Fragment in the order they were provided. 1429306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElements The mapping of shared element names to Views. The best guess 1439306f07b1d66f4974a81f781d29739b30124fff0George Mount * will be filled into sharedElements based on the transitionNames. 1449306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 1459306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {} 1469306f07b1d66f4974a81f781d29739b30124fff0George Mount 1479306f07b1d66f4974a81f781d29739b30124fff0George Mount 1489306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 1499306f07b1d66f4974a81f781d29739b30124fff0George Mount * Creates a snapshot of a shared element to be used by the remote Activity and reconstituted 1509306f07b1d66f4974a81f781d29739b30124fff0George Mount * with {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)}. A 1519306f07b1d66f4974a81f781d29739b30124fff0George Mount * null return value will mean that the remote Activity will have a null snapshot View in 1529306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and 1539306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}. 1549306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1559306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p>This is not called for Fragment Transitions.</p> 1569306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1579306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElement The shared element View to create a snapshot for. 1589306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param viewToGlobalMatrix A matrix containing a transform from the view to the screen 1599306f07b1d66f4974a81f781d29739b30124fff0George Mount * coordinates. 1609306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param screenBounds The bounds of shared element in screen coordinate space. This is 1619306f07b1d66f4974a81f781d29739b30124fff0George Mount * the bounds of the view with the viewToGlobalMatrix applied. 1629306f07b1d66f4974a81f781d29739b30124fff0George Mount * @return A snapshot to send to the remote Activity to be reconstituted with 1639306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)} and passed 1649306f07b1d66f4974a81f781d29739b30124fff0George Mount * into {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and 1659306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}. 1669306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 1679306f07b1d66f4974a81f781d29739b30124fff0George Mount public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, 1689306f07b1d66f4974a81f781d29739b30124fff0George Mount RectF screenBounds) { 169b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (sharedElement instanceof ImageView) { 170b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ImageView imageView = ((ImageView) sharedElement); 171b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Drawable d = imageView.getDrawable(); 172b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Drawable bg = imageView.getBackground(); 173b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (d != null && bg == null) { 174b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bitmap bitmap = createDrawableBitmap(d); 175b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (bitmap != null) { 176b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bundle bundle = new Bundle(); 177b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu bundle.putParcelable(BUNDLE_SNAPSHOT_BITMAP, bitmap); 178b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu bundle.putString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE, 179b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.getScaleType().toString()); 180b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (imageView.getScaleType() == ScaleType.MATRIX) { 181b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Matrix matrix = imageView.getImageMatrix(); 182b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu float[] values = new float[9]; 183b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu matrix.getValues(values); 184b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu bundle.putFloatArray(BUNDLE_SNAPSHOT_IMAGE_MATRIX, values); 185b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 186b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return bundle; 187b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 188b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 189b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 1909306f07b1d66f4974a81f781d29739b30124fff0George Mount int bitmapWidth = Math.round(screenBounds.width()); 1919306f07b1d66f4974a81f781d29739b30124fff0George Mount int bitmapHeight = Math.round(screenBounds.height()); 1929306f07b1d66f4974a81f781d29739b30124fff0George Mount Bitmap bitmap = null; 1939306f07b1d66f4974a81f781d29739b30124fff0George Mount if (bitmapWidth > 0 && bitmapHeight > 0) { 194b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu float scale = Math.min(1f, ((float)MAX_IMAGE_SIZE) / (bitmapWidth * bitmapHeight)); 195b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu bitmapWidth *= scale; 196b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu bitmapHeight *= scale; 1979306f07b1d66f4974a81f781d29739b30124fff0George Mount if (mTempMatrix == null) { 1989306f07b1d66f4974a81f781d29739b30124fff0George Mount mTempMatrix = new Matrix(); 1999306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2009306f07b1d66f4974a81f781d29739b30124fff0George Mount mTempMatrix.set(viewToGlobalMatrix); 2019306f07b1d66f4974a81f781d29739b30124fff0George Mount mTempMatrix.postTranslate(-screenBounds.left, -screenBounds.top); 202b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu mTempMatrix.postScale(scale, scale); 2039306f07b1d66f4974a81f781d29739b30124fff0George Mount bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 2049306f07b1d66f4974a81f781d29739b30124fff0George Mount Canvas canvas = new Canvas(bitmap); 2059306f07b1d66f4974a81f781d29739b30124fff0George Mount canvas.concat(mTempMatrix); 2069306f07b1d66f4974a81f781d29739b30124fff0George Mount sharedElement.draw(canvas); 2079306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2089306f07b1d66f4974a81f781d29739b30124fff0George Mount return bitmap; 2099306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2109306f07b1d66f4974a81f781d29739b30124fff0George Mount 2119306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 212b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu * Get a copy of bitmap of given drawable. 213b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu */ 214b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static Bitmap createDrawableBitmap(Drawable drawable) { 215b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int width = drawable.getIntrinsicWidth(); 216b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int height = drawable.getIntrinsicHeight(); 217b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (width <= 0 || height <= 0) { 218b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return null; 219b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 220b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu float scale = Math.min(1f, ((float)MAX_IMAGE_SIZE) / (width * height)); 221b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (drawable instanceof BitmapDrawable && scale == 1f) { 222b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu // return same bitmap if scale down not needed 223b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return ((BitmapDrawable) drawable).getBitmap(); 224b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 225b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int bitmapWidth = (int) (width * scale); 226b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int bitmapHeight = (int) (height * scale); 227b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 228b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Canvas canvas = new Canvas(bitmap); 229b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Rect existingBounds = drawable.getBounds(); 230b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int left = existingBounds.left; 231b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int top = existingBounds.top; 232b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int right = existingBounds.right; 233b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int bottom = existingBounds.bottom; 234b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu drawable.setBounds(0, 0, bitmapWidth, bitmapHeight); 235b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu drawable.draw(canvas); 236b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu drawable.setBounds(left, top, right, bottom); 237b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return bitmap; 238b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 239b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 240b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu /** 2419306f07b1d66f4974a81f781d29739b30124fff0George Mount * Reconstitutes a snapshot View from a Parcelable returned in 2429306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, 2439306f07b1d66f4974a81f781d29739b30124fff0George Mount * android.graphics.RectF)} to be used in {@link #onSharedElementStart(java.util.List, 2449306f07b1d66f4974a81f781d29739b30124fff0George Mount * java.util.List, java.util.List)} and {@link #onSharedElementEnd(java.util.List, 2459306f07b1d66f4974a81f781d29739b30124fff0George Mount * java.util.List, java.util.List)}. The returned View will be sized and positioned after 2469306f07b1d66f4974a81f781d29739b30124fff0George Mount * this call so that it is ready to be added to the decor View's overlay. 2479306f07b1d66f4974a81f781d29739b30124fff0George Mount * 2489306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p>This is not called for Fragment Transitions.</p> 2499306f07b1d66f4974a81f781d29739b30124fff0George Mount * 2509306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param context The Context used to create the snapshot View. 2519306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param snapshot The Parcelable returned by {@link #onCaptureSharedElementSnapshot( 2529306f07b1d66f4974a81f781d29739b30124fff0George Mount * android.view.View, android.graphics.Matrix, android.graphics.RectF)}. 2539306f07b1d66f4974a81f781d29739b30124fff0George Mount * @return A View to be sent in {@link #onSharedElementStart(java.util.List, java.util.List, 2549306f07b1d66f4974a81f781d29739b30124fff0George Mount * java.util.List)} and {@link #onSharedElementEnd(java.util.List, java.util.List, 2559306f07b1d66f4974a81f781d29739b30124fff0George Mount * java.util.List)}. A null value will produce a null snapshot value for those two methods. 2569306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 2579306f07b1d66f4974a81f781d29739b30124fff0George Mount public View onCreateSnapshotView(Context context, Parcelable snapshot) { 2589306f07b1d66f4974a81f781d29739b30124fff0George Mount ImageView view = null; 259b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (snapshot instanceof Bundle) { 260b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bundle bundle = (Bundle) snapshot; 261b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bitmap bitmap = (Bitmap) bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP); 262b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (bitmap == null) { 263b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return null; 264b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 265b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ImageView imageView = new ImageView(context); 266b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu view = imageView; 267b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setImageBitmap(bitmap); 268b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setScaleType( 269b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ScaleType.valueOf(bundle.getString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE))); 270b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (imageView.getScaleType() == ScaleType.MATRIX) { 271b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu float[] values = bundle.getFloatArray(BUNDLE_SNAPSHOT_IMAGE_MATRIX); 272b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Matrix matrix = new Matrix(); 273b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu matrix.setValues(values); 274b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setImageMatrix(matrix); 275b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 276b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } else if (snapshot instanceof Bitmap) { 2779306f07b1d66f4974a81f781d29739b30124fff0George Mount Bitmap bitmap = (Bitmap) snapshot; 2789306f07b1d66f4974a81f781d29739b30124fff0George Mount view = new ImageView(context); 2799306f07b1d66f4974a81f781d29739b30124fff0George Mount view.setImageBitmap(bitmap); 2809306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2819306f07b1d66f4974a81f781d29739b30124fff0George Mount return view; 2829306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2839306f07b1d66f4974a81f781d29739b30124fff0George Mount 2849306f07b1d66f4974a81f781d29739b30124fff0George Mount} 285