Home | History | Annotate | Download | only in app
      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