1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.support.v4.app; 17 18import android.content.Context; 19import android.content.res.Resources; 20import android.graphics.Bitmap; 21import android.graphics.Canvas; 22import android.graphics.Matrix; 23import android.graphics.RectF; 24import android.graphics.drawable.BitmapDrawable; 25import android.os.Parcelable; 26import android.view.View; 27import android.widget.ImageView; 28 29import java.util.List; 30import java.util.Map; 31 32/** 33 * Listener provided in 34 * {@link FragmentActivity#setEnterSharedElementCallback(SharedElementCallback)} and 35 * {@link FragmentActivity#setExitSharedElementCallback(SharedElementCallback)} 36 * to monitor the Activity transitions. The events can be used to customize Activity 37 * Transition behavior. 38 */ 39public abstract class SharedElementCallback { 40 private Matrix mTempMatrix; 41 42 /** 43 * Called immediately after the start state is set for the shared element. 44 * The shared element will start at the size and position of the shared element 45 * in the launching Activity or Fragment. 46 * 47 * @param sharedElementNames The names of the shared elements that were accepted into 48 * the View hierarchy. 49 * @param sharedElements The shared elements that are part of the View hierarchy. 50 * @param sharedElementSnapshots The Views containing snap shots of the shared element 51 * from the launching Window. These elements will not 52 * be part of the scene, but will be positioned relative 53 * to the Window decor View. This list is null for Fragment 54 * Transitions. 55 */ 56 public void onSharedElementStart(List<String> sharedElementNames, 57 List<View> sharedElements, List<View> sharedElementSnapshots) {} 58 59 /** 60 * Called after the end state is set for the shared element, but before the end state 61 * is captured by the shared element transition. 62 * <p> 63 * Any customization done in 64 * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} 65 * may need to be modified to the final state of the shared element if it is not 66 * automatically corrected by layout. For example, rotation or scale will not 67 * be affected by layout and if changed in {@link #onSharedElementStart(java.util.List, 68 * java.util.List, java.util.List)}, it will also have to be set here again to correct 69 * the end state. 70 * </p> 71 * 72 * @param sharedElementNames The names of the shared elements that were accepted into 73 * the View hierarchy. 74 * @param sharedElements The shared elements that are part of the View hierarchy. 75 * @param sharedElementSnapshots The Views containing snap shots of the shared element 76 * from the launching Window. These elements will not 77 * be part of the scene, but will be positioned relative 78 * to the Window decor View. This list will be null for 79 * Fragment Transitions. 80 */ 81 public void onSharedElementEnd(List<String> sharedElementNames, 82 List<View> sharedElements, List<View> sharedElementSnapshots) {} 83 84 /** 85 * Called after {@link #onMapSharedElements(java.util.List, java.util.Map)} when 86 * transferring shared elements in. Any shared elements that have no mapping will be in 87 * <var>rejectedSharedElements</var>. The elements remaining in 88 * <var>rejectedSharedElements</var> will be transitioned out of the Scene. If a 89 * View is removed from <var>rejectedSharedElements</var>, it must be handled by the 90 * <code>SharedElementListener</code>. 91 * <p> 92 * Views in rejectedSharedElements will have their position and size set to the 93 * position of the calling shared element, relative to the Window decor View and contain 94 * snapshots of the View from the calling Activity or Fragment. This 95 * view may be safely added to the decor View's overlay to remain in position. 96 * </p> 97 * <p>This method is not called for Fragment Transitions. All rejected shared elements 98 * will be handled by the exit transition.</p> 99 * 100 * @param rejectedSharedElements Views containing visual information of shared elements 101 * that are not part of the entering scene. These Views 102 * are positioned relative to the Window decor View. A 103 * View removed from this list will not be transitioned 104 * automatically. 105 */ 106 public void onRejectSharedElements(List<View> rejectedSharedElements) {} 107 108 /** 109 * Lets the SharedElementCallback adjust the mapping of shared element names to 110 * Views. 111 * 112 * @param names The names of all shared elements transferred from the calling Activity 113 * or Fragment in the order they were provided. 114 * @param sharedElements The mapping of shared element names to Views. The best guess 115 * will be filled into sharedElements based on the transitionNames. 116 */ 117 public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {} 118 119 120 /** 121 * Creates a snapshot of a shared element to be used by the remote Activity and reconstituted 122 * with {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)}. A 123 * null return value will mean that the remote Activity will have a null snapshot View in 124 * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and 125 * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}. 126 * 127 * <p>This is not called for Fragment Transitions.</p> 128 * 129 * @param sharedElement The shared element View to create a snapshot for. 130 * @param viewToGlobalMatrix A matrix containing a transform from the view to the screen 131 * coordinates. 132 * @param screenBounds The bounds of shared element in screen coordinate space. This is 133 * the bounds of the view with the viewToGlobalMatrix applied. 134 * @return A snapshot to send to the remote Activity to be reconstituted with 135 * {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)} and passed 136 * into {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and 137 * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}. 138 */ 139 public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, 140 RectF screenBounds) { 141 int bitmapWidth = Math.round(screenBounds.width()); 142 int bitmapHeight = Math.round(screenBounds.height()); 143 Bitmap bitmap = null; 144 if (bitmapWidth > 0 && bitmapHeight > 0) { 145 if (mTempMatrix == null) { 146 mTempMatrix = new Matrix(); 147 } 148 mTempMatrix.set(viewToGlobalMatrix); 149 mTempMatrix.postTranslate(-screenBounds.left, -screenBounds.top); 150 bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 151 Canvas canvas = new Canvas(bitmap); 152 canvas.concat(mTempMatrix); 153 sharedElement.draw(canvas); 154 } 155 return bitmap; 156 } 157 158 /** 159 * Reconstitutes a snapshot View from a Parcelable returned in 160 * {@link #onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, 161 * android.graphics.RectF)} to be used in {@link #onSharedElementStart(java.util.List, 162 * java.util.List, java.util.List)} and {@link #onSharedElementEnd(java.util.List, 163 * java.util.List, java.util.List)}. The returned View will be sized and positioned after 164 * this call so that it is ready to be added to the decor View's overlay. 165 * 166 * <p>This is not called for Fragment Transitions.</p> 167 * 168 * @param context The Context used to create the snapshot View. 169 * @param snapshot The Parcelable returned by {@link #onCaptureSharedElementSnapshot( 170 * android.view.View, android.graphics.Matrix, android.graphics.RectF)}. 171 * @return A View to be sent in {@link #onSharedElementStart(java.util.List, java.util.List, 172 * java.util.List)} and {@link #onSharedElementEnd(java.util.List, java.util.List, 173 * java.util.List)}. A null value will produce a null snapshot value for those two methods. 174 */ 175 public View onCreateSnapshotView(Context context, Parcelable snapshot) { 176 ImageView view = null; 177 if (snapshot instanceof Bitmap) { 178 Bitmap bitmap = (Bitmap) snapshot; 179 view = new ImageView(context); 180 view.setImageBitmap(bitmap); 181 } 182 return view; 183 } 184 185} 186