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 */ 16 package android.app; 17 18 import android.content.Context; 19 import android.content.res.Resources; 20 import android.graphics.Bitmap; 21 import android.graphics.Canvas; 22 import android.graphics.Matrix; 23 import android.graphics.RectF; 24 import android.graphics.drawable.BitmapDrawable; 25 import android.os.Parcelable; 26 import android.transition.TransitionUtils; 27 import android.view.View; 28 29 import java.util.List; 30 import java.util.Map; 31 32 /** 33 * Listener provided in 34 * {@link Activity#setEnterSharedElementCallback(SharedElementCallback)} and 35 * {@link Activity#setExitSharedElementCallback(SharedElementCallback)} as well as 36 * {@link Fragment#setEnterSharedElementCallback(SharedElementCallback)} and 37 * {@link Fragment#setExitSharedElementCallback(SharedElementCallback)} 38 * to monitor the Shared element transitions. The events can be used to customize Activity 39 * and Fragment Transition behavior. 40 */ 41 public abstract class SharedElementCallback { 42 private Matrix mTempMatrix; 43 44 static final SharedElementCallback NULL_CALLBACK = new SharedElementCallback() { 45 }; 46 47 /** 48 * Called immediately after the start state is set for the shared element. 49 * The shared element will start at the size and position of the shared element 50 * in the launching Activity or Fragment. 51 * 52 * @param sharedElementNames The names of the shared elements that were accepted into 53 * the View hierarchy. 54 * @param sharedElements The shared elements that are part of the View hierarchy. 55 * @param sharedElementSnapshots The Views containing snap shots of the shared element 56 * from the launching Window. These elements will not 57 * be part of the scene, but will be positioned relative 58 * to the Window decor View. This list is null for Fragment 59 * Transitions. 60 */ 61 public void onSharedElementStart(List<String> sharedElementNames, 62 List<View> sharedElements, List<View> sharedElementSnapshots) {} 63 64 /** 65 * Called after the end state is set for the shared element, but before the end state 66 * is captured by the shared element transition. 67 * <p> 68 * Any customization done in 69 * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} 70 * may need to be modified to the final state of the shared element if it is not 71 * automatically corrected by layout. For example, rotation or scale will not 72 * be affected by layout and if changed in {@link #onSharedElementStart(java.util.List, 73 * java.util.List, java.util.List)}, it will also have to be set here again to correct 74 * the end state. 75 * </p> 76 * 77 * @param sharedElementNames The names of the shared elements that were accepted into 78 * the View hierarchy. 79 * @param sharedElements The shared elements that are part of the View hierarchy. 80 * @param sharedElementSnapshots The Views containing snap shots of the shared element 81 * from the launching Window. These elements will not 82 * be part of the scene, but will be positioned relative 83 * to the Window decor View. This list will be null for 84 * Fragment Transitions. 85 */ 86 public void onSharedElementEnd(List<String> sharedElementNames, 87 List<View> sharedElements, List<View> sharedElementSnapshots) {} 88 89 /** 90 * Called after {@link #onMapSharedElements(java.util.List, java.util.Map)} when 91 * transferring shared elements in. Any shared elements that have no mapping will be in 92 * <var>rejectedSharedElements</var>. The elements remaining in 93 * <var>rejectedSharedElements</var> will be transitioned out of the Scene. If a 94 * View is removed from <var>rejectedSharedElements</var>, it must be handled by the 95 * <code>SharedElementCallback</code>. 96 * <p> 97 * Views in rejectedSharedElements will have their position and size set to the 98 * position of the calling shared element, relative to the Window decor View and contain 99 * snapshots of the View from the calling Activity or Fragment. This 100 * view may be safely added to the decor View's overlay to remain in position. 101 * </p> 102 * <p>This method is not called for Fragment Transitions. All rejected shared elements 103 * will be handled by the exit transition.</p> 104 * 105 * @param rejectedSharedElements Views containing visual information of shared elements 106 * that are not part of the entering scene. These Views 107 * are positioned relative to the Window decor View. A 108 * View removed from this list will not be transitioned 109 * automatically. 110 */ 111 public void onRejectSharedElements(List<View> rejectedSharedElements) {} 112 113 /** 114 * Lets the SharedElementCallback adjust the mapping of shared element names to 115 * Views. 116 * 117 * @param names The names of all shared elements transferred from the calling Activity 118 * or Fragment in the order they were provided. 119 * @param sharedElements The mapping of shared element names to Views. The best guess 120 * will be filled into sharedElements based on the transitionNames. 121 */ 122 public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {} 123 124 /** 125 * Creates a snapshot of a shared element to be used by the remote Activity and reconstituted 126 * with {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)}. A 127 * null return value will mean that the remote Activity will have a null snapshot View in 128 * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and 129 * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}. 130 * 131 * <p>This is not called for Fragment Transitions.</p> 132 * 133 * @param sharedElement The shared element View to create a snapshot for. 134 * @param viewToGlobalMatrix A matrix containing a transform from the view to the screen 135 * coordinates. 136 * @param screenBounds The bounds of shared element in screen coordinate space. This is 137 * the bounds of the view with the viewToGlobalMatrix applied. 138 * @return A snapshot to send to the remote Activity to be reconstituted with 139 * {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)} and passed 140 * into {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and 141 * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}. 142 */ 143 public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, 144 RectF screenBounds) { 145 if (mTempMatrix == null) { 146 mTempMatrix = new Matrix(viewToGlobalMatrix); 147 } else { 148 mTempMatrix.set(viewToGlobalMatrix); 149 } 150 return TransitionUtils.createViewBitmap(sharedElement, mTempMatrix, screenBounds); 151 } 152 153 /** 154 * Reconstitutes a snapshot View from a Parcelable returned in 155 * {@link #onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, 156 * android.graphics.RectF)} to be used in {@link #onSharedElementStart(java.util.List, 157 * java.util.List, java.util.List)} and {@link #onSharedElementEnd(java.util.List, 158 * java.util.List, java.util.List)}. The returned View will be sized and positioned after 159 * this call so that it is ready to be added to the decor View's overlay. 160 * 161 * <p>This is not called for Fragment Transitions.</p> 162 * 163 * @param context The Context used to create the snapshot View. 164 * @param snapshot The Parcelable returned by {@link #onCaptureSharedElementSnapshot( 165 * android.view.View, android.graphics.Matrix, android.graphics.RectF)}. 166 * @return A View to be sent in {@link #onSharedElementStart(java.util.List, java.util.List, 167 * java.util.List)} and {@link #onSharedElementEnd(java.util.List, java.util.List, 168 * java.util.List)}. A null value will produce a null snapshot value for those two methods. 169 */ 170 public View onCreateSnapshotView(Context context, Parcelable snapshot) { 171 View view = null; 172 if (snapshot instanceof Bitmap) { 173 Bitmap bitmap = (Bitmap) snapshot; 174 view = new View(context); 175 Resources resources = context.getResources(); 176 view.setBackground(new BitmapDrawable(resources, bitmap)); 177 } 178 return view; 179 } 180 } 181