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.graphics.Bitmap; 209306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.Canvas; 219306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.Matrix; 22b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.graphics.Rect; 239306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.RectF; 249306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.graphics.drawable.BitmapDrawable; 25b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.graphics.drawable.Drawable; 26b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.os.Bundle; 279306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.os.Parcelable; 289306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.view.View; 299306f07b1d66f4974a81f781d29739b30124fff0George Mountimport android.widget.ImageView; 30b81a2943b9e150c6caca969e62c5375928c4cd1cDake Guimport android.widget.ImageView.ScaleType; 319306f07b1d66f4974a81f781d29739b30124fff0George Mount 329306f07b1d66f4974a81f781d29739b30124fff0George Mountimport java.util.List; 339306f07b1d66f4974a81f781d29739b30124fff0George Mountimport java.util.Map; 349306f07b1d66f4974a81f781d29739b30124fff0George Mount 359306f07b1d66f4974a81f781d29739b30124fff0George Mount/** 369306f07b1d66f4974a81f781d29739b30124fff0George Mount * Listener provided in 379306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link FragmentActivity#setEnterSharedElementCallback(SharedElementCallback)} and 389306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link FragmentActivity#setExitSharedElementCallback(SharedElementCallback)} 399306f07b1d66f4974a81f781d29739b30124fff0George Mount * to monitor the Activity transitions. The events can be used to customize Activity 409306f07b1d66f4974a81f781d29739b30124fff0George Mount * Transition behavior. 419306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 429306f07b1d66f4974a81f781d29739b30124fff0George Mountpublic abstract class SharedElementCallback { 439306f07b1d66f4974a81f781d29739b30124fff0George Mount private Matrix mTempMatrix; 44b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static int MAX_IMAGE_SIZE = (1024 * 1024); 45b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static final String BUNDLE_SNAPSHOT_BITMAP = "sharedElement:snapshot:bitmap"; 46b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static final String BUNDLE_SNAPSHOT_IMAGE_SCALETYPE = "sharedElement:snapshot:imageScaleType"; 47b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static final String BUNDLE_SNAPSHOT_IMAGE_MATRIX = "sharedElement:snapshot:imageMatrix"; 489306f07b1d66f4974a81f781d29739b30124fff0George Mount 499306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 500094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * In Activity Transitions, onSharedElementStart is called immediately before 510094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * capturing the start of the shared element state on enter and reenter transitions and 520094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * immediately before capturing the end of the shared element state for exit and return 530094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * transitions. 540094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 550094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * In Fragment Transitions, onSharedElementStart is called immediately before capturing the 560094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * start state of all shared element transitions. 570094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 580094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * This call can be used to adjust the transition start state by modifying the shared 590094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * element Views. Note that no layout step will be executed between onSharedElementStart 600094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * and the transition state capture. 610094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 620094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * For Activity Transitions, any changes made in {@link #onSharedElementEnd(List, List, List)} 630094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * that are not updated during layout should be corrected in onSharedElementStart for exit and 640094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * return transitions. For example, rotation or scale will not be affected by layout and 650094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * if changed in {@link #onSharedElementEnd(List, List, List)}, it will also have to be reset 660094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * in onSharedElementStart again to correct the end state. 679306f07b1d66f4974a81f781d29739b30124fff0George Mount * 689306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElementNames The names of the shared elements that were accepted into 699306f07b1d66f4974a81f781d29739b30124fff0George Mount * the View hierarchy. 709306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElements The shared elements that are part of the View hierarchy. 719306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElementSnapshots The Views containing snap shots of the shared element 729306f07b1d66f4974a81f781d29739b30124fff0George Mount * from the launching Window. These elements will not 739306f07b1d66f4974a81f781d29739b30124fff0George Mount * be part of the scene, but will be positioned relative 749306f07b1d66f4974a81f781d29739b30124fff0George Mount * to the Window decor View. This list is null for Fragment 759306f07b1d66f4974a81f781d29739b30124fff0George Mount * Transitions. 769306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 779306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onSharedElementStart(List<String> sharedElementNames, 789306f07b1d66f4974a81f781d29739b30124fff0George Mount List<View> sharedElements, List<View> sharedElementSnapshots) {} 799306f07b1d66f4974a81f781d29739b30124fff0George Mount 809306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 810094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * In Activity Transitions, onSharedElementEnd is called immediately before 820094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * capturing the end of the shared element state on enter and reenter transitions and 830094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * immediately before capturing the start of the shared element state for exit and return 840094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * transitions. 850094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 860094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * In Fragment Transitions, onSharedElementEnd is called immediately before capturing the 870094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * end state of all shared element transitions. 880094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * <p> 890094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * This call can be used to adjust the transition end state by modifying the shared 900094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * element Views. Note that no layout step will be executed between onSharedElementEnd 910094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * and the transition state capture. 929306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p> 930094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * Any changes made in {@link #onSharedElementStart(List, List, List)} that are not updated 940094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * during layout should be corrected in onSharedElementEnd. For example, rotation or scale 950094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * will not be affected by layout and if changed in 960094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * {@link #onSharedElementStart(List, List, List)}, it will also have to be reset in 970094e26ee39675042cf0545ecdf3b5b3a363efb8George Mount * onSharedElementEnd again to correct the end state. 989306f07b1d66f4974a81f781d29739b30124fff0George Mount * 999306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElementNames The names of the shared elements that were accepted into 1009306f07b1d66f4974a81f781d29739b30124fff0George Mount * the View hierarchy. 1019306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElements The shared elements that are part of the View hierarchy. 1029306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElementSnapshots The Views containing snap shots of the shared element 1039306f07b1d66f4974a81f781d29739b30124fff0George Mount * from the launching Window. These elements will not 1049306f07b1d66f4974a81f781d29739b30124fff0George Mount * be part of the scene, but will be positioned relative 1059306f07b1d66f4974a81f781d29739b30124fff0George Mount * to the Window decor View. This list will be null for 1069306f07b1d66f4974a81f781d29739b30124fff0George Mount * Fragment Transitions. 1079306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 1089306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onSharedElementEnd(List<String> sharedElementNames, 1099306f07b1d66f4974a81f781d29739b30124fff0George Mount List<View> sharedElements, List<View> sharedElementSnapshots) {} 1109306f07b1d66f4974a81f781d29739b30124fff0George Mount 1119306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 1129306f07b1d66f4974a81f781d29739b30124fff0George Mount * Called after {@link #onMapSharedElements(java.util.List, java.util.Map)} when 1139306f07b1d66f4974a81f781d29739b30124fff0George Mount * transferring shared elements in. Any shared elements that have no mapping will be in 1149306f07b1d66f4974a81f781d29739b30124fff0George Mount * <var>rejectedSharedElements</var>. The elements remaining in 1159306f07b1d66f4974a81f781d29739b30124fff0George Mount * <var>rejectedSharedElements</var> will be transitioned out of the Scene. If a 1169306f07b1d66f4974a81f781d29739b30124fff0George Mount * View is removed from <var>rejectedSharedElements</var>, it must be handled by the 1179306f07b1d66f4974a81f781d29739b30124fff0George Mount * <code>SharedElementListener</code>. 1189306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p> 1199306f07b1d66f4974a81f781d29739b30124fff0George Mount * Views in rejectedSharedElements will have their position and size set to the 1209306f07b1d66f4974a81f781d29739b30124fff0George Mount * position of the calling shared element, relative to the Window decor View and contain 1219306f07b1d66f4974a81f781d29739b30124fff0George Mount * snapshots of the View from the calling Activity or Fragment. This 1229306f07b1d66f4974a81f781d29739b30124fff0George Mount * view may be safely added to the decor View's overlay to remain in position. 1239306f07b1d66f4974a81f781d29739b30124fff0George Mount * </p> 1249306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p>This method is not called for Fragment Transitions. All rejected shared elements 1259306f07b1d66f4974a81f781d29739b30124fff0George Mount * will be handled by the exit transition.</p> 1269306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1279306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param rejectedSharedElements Views containing visual information of shared elements 1289306f07b1d66f4974a81f781d29739b30124fff0George Mount * that are not part of the entering scene. These Views 1299306f07b1d66f4974a81f781d29739b30124fff0George Mount * are positioned relative to the Window decor View. A 1309306f07b1d66f4974a81f781d29739b30124fff0George Mount * View removed from this list will not be transitioned 1319306f07b1d66f4974a81f781d29739b30124fff0George Mount * automatically. 1329306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 1339306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onRejectSharedElements(List<View> rejectedSharedElements) {} 1349306f07b1d66f4974a81f781d29739b30124fff0George Mount 1359306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 1369306f07b1d66f4974a81f781d29739b30124fff0George Mount * Lets the SharedElementCallback adjust the mapping of shared element names to 1379306f07b1d66f4974a81f781d29739b30124fff0George Mount * Views. 1389306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1399306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param names The names of all shared elements transferred from the calling Activity 1409306f07b1d66f4974a81f781d29739b30124fff0George Mount * or Fragment in the order they were provided. 1419306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElements The mapping of shared element names to Views. The best guess 1429306f07b1d66f4974a81f781d29739b30124fff0George Mount * will be filled into sharedElements based on the transitionNames. 1439306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 1449306f07b1d66f4974a81f781d29739b30124fff0George Mount public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {} 1459306f07b1d66f4974a81f781d29739b30124fff0George Mount 1469306f07b1d66f4974a81f781d29739b30124fff0George Mount 1479306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 1489306f07b1d66f4974a81f781d29739b30124fff0George Mount * Creates a snapshot of a shared element to be used by the remote Activity and reconstituted 1499306f07b1d66f4974a81f781d29739b30124fff0George Mount * with {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)}. A 1509306f07b1d66f4974a81f781d29739b30124fff0George Mount * null return value will mean that the remote Activity will have a null snapshot View in 1519306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and 1529306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}. 1539306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1549306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p>This is not called for Fragment Transitions.</p> 1559306f07b1d66f4974a81f781d29739b30124fff0George Mount * 1569306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param sharedElement The shared element View to create a snapshot for. 1579306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param viewToGlobalMatrix A matrix containing a transform from the view to the screen 1589306f07b1d66f4974a81f781d29739b30124fff0George Mount * coordinates. 1599306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param screenBounds The bounds of shared element in screen coordinate space. This is 1609306f07b1d66f4974a81f781d29739b30124fff0George Mount * the bounds of the view with the viewToGlobalMatrix applied. 1619306f07b1d66f4974a81f781d29739b30124fff0George Mount * @return A snapshot to send to the remote Activity to be reconstituted with 1629306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)} and passed 1639306f07b1d66f4974a81f781d29739b30124fff0George Mount * into {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and 1649306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}. 1659306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 1669306f07b1d66f4974a81f781d29739b30124fff0George Mount public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, 1679306f07b1d66f4974a81f781d29739b30124fff0George Mount RectF screenBounds) { 168b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (sharedElement instanceof ImageView) { 169b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ImageView imageView = ((ImageView) sharedElement); 170b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Drawable d = imageView.getDrawable(); 171b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Drawable bg = imageView.getBackground(); 172b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (d != null && bg == null) { 173b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bitmap bitmap = createDrawableBitmap(d); 174b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (bitmap != null) { 175b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bundle bundle = new Bundle(); 176b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu bundle.putParcelable(BUNDLE_SNAPSHOT_BITMAP, bitmap); 177b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu bundle.putString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE, 178b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.getScaleType().toString()); 179b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (imageView.getScaleType() == ScaleType.MATRIX) { 180b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Matrix matrix = imageView.getImageMatrix(); 181b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu float[] values = new float[9]; 182b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu matrix.getValues(values); 183b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu bundle.putFloatArray(BUNDLE_SNAPSHOT_IMAGE_MATRIX, values); 184b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 185b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return bundle; 186b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 187b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 188b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 1899306f07b1d66f4974a81f781d29739b30124fff0George Mount int bitmapWidth = Math.round(screenBounds.width()); 1909306f07b1d66f4974a81f781d29739b30124fff0George Mount int bitmapHeight = Math.round(screenBounds.height()); 1919306f07b1d66f4974a81f781d29739b30124fff0George Mount Bitmap bitmap = null; 1929306f07b1d66f4974a81f781d29739b30124fff0George Mount if (bitmapWidth > 0 && bitmapHeight > 0) { 193fa79d6fc148a0642f240377b8ce82acfee7bb890Aurimas Liutikas float scale = Math.min(1f, ((float) MAX_IMAGE_SIZE) / (bitmapWidth * bitmapHeight)); 194fa79d6fc148a0642f240377b8ce82acfee7bb890Aurimas Liutikas bitmapWidth = (int) (bitmapWidth * scale); 195fa79d6fc148a0642f240377b8ce82acfee7bb890Aurimas Liutikas bitmapHeight = (int) (bitmapHeight * scale); 1969306f07b1d66f4974a81f781d29739b30124fff0George Mount if (mTempMatrix == null) { 1979306f07b1d66f4974a81f781d29739b30124fff0George Mount mTempMatrix = new Matrix(); 1989306f07b1d66f4974a81f781d29739b30124fff0George Mount } 1999306f07b1d66f4974a81f781d29739b30124fff0George Mount mTempMatrix.set(viewToGlobalMatrix); 2009306f07b1d66f4974a81f781d29739b30124fff0George Mount mTempMatrix.postTranslate(-screenBounds.left, -screenBounds.top); 201b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu mTempMatrix.postScale(scale, scale); 2029306f07b1d66f4974a81f781d29739b30124fff0George Mount bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 2039306f07b1d66f4974a81f781d29739b30124fff0George Mount Canvas canvas = new Canvas(bitmap); 2049306f07b1d66f4974a81f781d29739b30124fff0George Mount canvas.concat(mTempMatrix); 2059306f07b1d66f4974a81f781d29739b30124fff0George Mount sharedElement.draw(canvas); 2069306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2079306f07b1d66f4974a81f781d29739b30124fff0George Mount return bitmap; 2089306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2099306f07b1d66f4974a81f781d29739b30124fff0George Mount 2109306f07b1d66f4974a81f781d29739b30124fff0George Mount /** 211b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu * Get a copy of bitmap of given drawable. 212b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu */ 213b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu private static Bitmap createDrawableBitmap(Drawable drawable) { 214b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int width = drawable.getIntrinsicWidth(); 215b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int height = drawable.getIntrinsicHeight(); 216b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (width <= 0 || height <= 0) { 217b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return null; 218b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 219b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu float scale = Math.min(1f, ((float)MAX_IMAGE_SIZE) / (width * height)); 220b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (drawable instanceof BitmapDrawable && scale == 1f) { 221b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu // return same bitmap if scale down not needed 222b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return ((BitmapDrawable) drawable).getBitmap(); 223b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 224b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int bitmapWidth = (int) (width * scale); 225b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int bitmapHeight = (int) (height * scale); 226b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 227b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Canvas canvas = new Canvas(bitmap); 228b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Rect existingBounds = drawable.getBounds(); 229b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int left = existingBounds.left; 230b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int top = existingBounds.top; 231b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int right = existingBounds.right; 232b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu int bottom = existingBounds.bottom; 233b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu drawable.setBounds(0, 0, bitmapWidth, bitmapHeight); 234b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu drawable.draw(canvas); 235b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu drawable.setBounds(left, top, right, bottom); 236b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return bitmap; 237b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 238b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu 239b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu /** 2409306f07b1d66f4974a81f781d29739b30124fff0George Mount * Reconstitutes a snapshot View from a Parcelable returned in 2419306f07b1d66f4974a81f781d29739b30124fff0George Mount * {@link #onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, 2429306f07b1d66f4974a81f781d29739b30124fff0George Mount * android.graphics.RectF)} to be used in {@link #onSharedElementStart(java.util.List, 2439306f07b1d66f4974a81f781d29739b30124fff0George Mount * java.util.List, java.util.List)} and {@link #onSharedElementEnd(java.util.List, 2449306f07b1d66f4974a81f781d29739b30124fff0George Mount * java.util.List, java.util.List)}. The returned View will be sized and positioned after 2459306f07b1d66f4974a81f781d29739b30124fff0George Mount * this call so that it is ready to be added to the decor View's overlay. 2469306f07b1d66f4974a81f781d29739b30124fff0George Mount * 2479306f07b1d66f4974a81f781d29739b30124fff0George Mount * <p>This is not called for Fragment Transitions.</p> 2489306f07b1d66f4974a81f781d29739b30124fff0George Mount * 2499306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param context The Context used to create the snapshot View. 2509306f07b1d66f4974a81f781d29739b30124fff0George Mount * @param snapshot The Parcelable returned by {@link #onCaptureSharedElementSnapshot( 2519306f07b1d66f4974a81f781d29739b30124fff0George Mount * android.view.View, android.graphics.Matrix, android.graphics.RectF)}. 2529306f07b1d66f4974a81f781d29739b30124fff0George Mount * @return A View to be sent in {@link #onSharedElementStart(java.util.List, java.util.List, 2539306f07b1d66f4974a81f781d29739b30124fff0George Mount * java.util.List)} and {@link #onSharedElementEnd(java.util.List, java.util.List, 2549306f07b1d66f4974a81f781d29739b30124fff0George Mount * java.util.List)}. A null value will produce a null snapshot value for those two methods. 2559306f07b1d66f4974a81f781d29739b30124fff0George Mount */ 2569306f07b1d66f4974a81f781d29739b30124fff0George Mount public View onCreateSnapshotView(Context context, Parcelable snapshot) { 2579306f07b1d66f4974a81f781d29739b30124fff0George Mount ImageView view = null; 258b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (snapshot instanceof Bundle) { 259b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bundle bundle = (Bundle) snapshot; 260b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Bitmap bitmap = (Bitmap) bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP); 261b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (bitmap == null) { 262b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu return null; 263b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 264b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ImageView imageView = new ImageView(context); 265b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu view = imageView; 266b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setImageBitmap(bitmap); 267b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setScaleType( 268b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu ScaleType.valueOf(bundle.getString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE))); 269b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu if (imageView.getScaleType() == ScaleType.MATRIX) { 270b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu float[] values = bundle.getFloatArray(BUNDLE_SNAPSHOT_IMAGE_MATRIX); 271b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu Matrix matrix = new Matrix(); 272b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu matrix.setValues(values); 273b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu imageView.setImageMatrix(matrix); 274b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } 275b81a2943b9e150c6caca969e62c5375928c4cd1cDake Gu } else if (snapshot instanceof Bitmap) { 2769306f07b1d66f4974a81f781d29739b30124fff0George Mount Bitmap bitmap = (Bitmap) snapshot; 2779306f07b1d66f4974a81f781d29739b30124fff0George Mount view = new ImageView(context); 2789306f07b1d66f4974a81f781d29739b30124fff0George Mount view.setImageBitmap(bitmap); 2799306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2809306f07b1d66f4974a81f781d29739b30124fff0George Mount return view; 2819306f07b1d66f4974a81f781d29739b30124fff0George Mount } 2829306f07b1d66f4974a81f781d29739b30124fff0George Mount 2830d5b0e011d7db522a576450593cf38170b997501Abhinav Baid /** 2840d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * Called during an Activity Transition when the shared elements have arrived at the 2850d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * final location and are ready to be transferred. This method is called for both the 2860d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * source and destination Activities. 2870d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * <p> 2880d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * When the shared elements are ready to be transferred, 2890d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * {@link OnSharedElementsReadyListener#onSharedElementsReady()} 2900d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * must be called to trigger the transfer. 2910d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * <p> 2920d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * The default behavior is to trigger the transfer immediately. 2930d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * 2940d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * @param sharedElementNames The names of the shared elements that are being transferred.. 2950d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * @param sharedElements The shared elements that are part of the View hierarchy. 2960d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * @param listener The listener to call when the shared elements are ready to be hidden 2970d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * in the source Activity or shown in the destination Activity. 2980d5b0e011d7db522a576450593cf38170b997501Abhinav Baid */ 2990d5b0e011d7db522a576450593cf38170b997501Abhinav Baid public void onSharedElementsArrived(List<String> sharedElementNames, 3000d5b0e011d7db522a576450593cf38170b997501Abhinav Baid List<View> sharedElements, OnSharedElementsReadyListener listener) { 3010d5b0e011d7db522a576450593cf38170b997501Abhinav Baid listener.onSharedElementsReady(); 3020d5b0e011d7db522a576450593cf38170b997501Abhinav Baid } 3030d5b0e011d7db522a576450593cf38170b997501Abhinav Baid 3040d5b0e011d7db522a576450593cf38170b997501Abhinav Baid /** 3050d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * Listener to be called after {@link 3060d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * SharedElementCallback#onSharedElementsArrived(List, List, OnSharedElementsReadyListener)} 3070d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * when the shared elements are ready to be hidden in the source Activity and shown in the 3080d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * destination Activity. 3090d5b0e011d7db522a576450593cf38170b997501Abhinav Baid */ 3100d5b0e011d7db522a576450593cf38170b997501Abhinav Baid public interface OnSharedElementsReadyListener { 3110d5b0e011d7db522a576450593cf38170b997501Abhinav Baid 3120d5b0e011d7db522a576450593cf38170b997501Abhinav Baid /** 3130d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * Call this method during or after the OnSharedElementsReadyListener has been received 3140d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * in {@link SharedElementCallback#onSharedElementsArrived(List, List, 3150d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * OnSharedElementsReadyListener)} to indicate that the shared elements are ready to be 3160d5b0e011d7db522a576450593cf38170b997501Abhinav Baid * hidden in the source and shown in the destination Activity. 3170d5b0e011d7db522a576450593cf38170b997501Abhinav Baid */ 3180d5b0e011d7db522a576450593cf38170b997501Abhinav Baid void onSharedElementsReady(); 3190d5b0e011d7db522a576450593cf38170b997501Abhinav Baid } 3209306f07b1d66f4974a81f781d29739b30124fff0George Mount} 321