ActivityTransitionState.java revision 62ab9b78b77b7dd851c47115f4d8d7611d657585
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.app; 17 18import android.os.Bundle; 19import android.os.ResultReceiver; 20import android.util.ArrayMap; 21import android.view.View; 22import android.view.Window; 23 24import java.util.ArrayList; 25 26/** 27 * This class contains all persistence-related functionality for Activity Transitions. 28 * Activities start exit and enter Activity Transitions through this class. 29 */ 30class ActivityTransitionState { 31 32 private static final String ENTERING_SHARED_ELEMENTS = "android:enteringSharedElements"; 33 34 private static final String ENTERING_MAPPED_FROM = "android:enteringMappedFrom"; 35 36 private static final String ENTERING_MAPPED_TO = "android:enteringMappedTo"; 37 38 private static final String EXITING_MAPPED_FROM = "android:exitingMappedFrom"; 39 40 private static final String EXITING_MAPPED_TO = "android:exitingMappedTo"; 41 42 /** 43 * The shared elements that the calling Activity has said that they transferred to this 44 * Activity. 45 */ 46 private ArrayList<String> mEnteringNames; 47 48 /** 49 * The shared elements that this Activity as accepted and mapped to local Views. 50 */ 51 private ArrayList<String> mEnteringFrom; 52 53 /** 54 * The names of local Views that are mapped to those elements in mEnteringFrom. 55 */ 56 private ArrayList<String> mEnteringTo; 57 58 /** 59 * The names of shared elements that were shared to the called Activity. 60 */ 61 private ArrayList<String> mExitingFrom; 62 63 /** 64 * The names of local Views that were shared out, mapped to those elements in mExitingFrom. 65 */ 66 private ArrayList<String> mExitingTo; 67 68 /** 69 * The ActivityOptions used to call an Activity. Used to make the elements restore 70 * Visibility of exited Views. 71 */ 72 private ActivityOptions mCalledActivityOptions; 73 74 /** 75 * We must be able to cancel entering transitions to stop changing the Window to 76 * opaque when we exit before making the Window opaque. 77 */ 78 private EnterTransitionCoordinator mEnterTransitionCoordinator; 79 80 /** 81 * ActivityOptions used on entering this Activity. 82 */ 83 private ActivityOptions mEnterActivityOptions; 84 85 /** 86 * Has an exit transition been started? If so, we don't want to double-exit. 87 */ 88 private boolean mHasExited; 89 90 public ActivityTransitionState() { 91 } 92 93 public void readState(Bundle bundle) { 94 if (bundle != null) { 95 if (mEnterTransitionCoordinator == null || mEnterTransitionCoordinator.isReturning()) { 96 mEnteringNames = bundle.getStringArrayList(ENTERING_SHARED_ELEMENTS); 97 mEnteringFrom = bundle.getStringArrayList(ENTERING_MAPPED_FROM); 98 mEnteringTo = bundle.getStringArrayList(ENTERING_MAPPED_TO); 99 } 100 if (mEnterTransitionCoordinator == null) { 101 mExitingFrom = bundle.getStringArrayList(EXITING_MAPPED_FROM); 102 mExitingTo = bundle.getStringArrayList(EXITING_MAPPED_TO); 103 } 104 } 105 } 106 107 public void saveState(Bundle bundle) { 108 if (mEnteringNames != null) { 109 bundle.putStringArrayList(ENTERING_SHARED_ELEMENTS, mEnteringNames); 110 bundle.putStringArrayList(ENTERING_MAPPED_FROM, mEnteringFrom); 111 bundle.putStringArrayList(ENTERING_MAPPED_TO, mEnteringTo); 112 } 113 if (mExitingFrom != null) { 114 bundle.putStringArrayList(EXITING_MAPPED_FROM, mExitingFrom); 115 bundle.putStringArrayList(EXITING_MAPPED_TO, mExitingTo); 116 } 117 } 118 119 public void setEnterActivityOptions(Activity activity, ActivityOptions options) { 120 if (activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS) 121 && options != null && mEnterActivityOptions == null 122 && options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) { 123 mEnterActivityOptions = options; 124 if (mEnterActivityOptions.isReturning()) { 125 int result = mEnterActivityOptions.getResultCode(); 126 if (result != 0) { 127 activity.onActivityReenter(result, mEnterActivityOptions.getResultData()); 128 } 129 } 130 } 131 } 132 133 public void enterReady(Activity activity) { 134 if (mEnterActivityOptions == null) { 135 return; 136 } 137 mHasExited = false; 138 ArrayList<String> sharedElementNames = mEnterActivityOptions.getSharedElementNames(); 139 ResultReceiver resultReceiver = mEnterActivityOptions.getResultReceiver(); 140 if (mEnterActivityOptions.isReturning()) { 141 if (mCalledActivityOptions != null) { 142 mCalledActivityOptions.dispatchActivityStopped(); 143 mCalledActivityOptions = null; 144 } 145 activity.getWindow().getDecorView().setVisibility(View.VISIBLE); 146 mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity, 147 resultReceiver, sharedElementNames, mExitingFrom, mExitingTo); 148 } else { 149 mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity, 150 resultReceiver, sharedElementNames, null, null); 151 mEnteringNames = sharedElementNames; 152 mEnteringFrom = mEnterTransitionCoordinator.getAcceptedNames(); 153 mEnteringTo = mEnterTransitionCoordinator.getMappedNames(); 154 } 155 mExitingFrom = null; 156 mExitingTo = null; 157 mEnterActivityOptions = null; 158 } 159 160 public void onStop() { 161 if (mCalledActivityOptions != null) { 162 mCalledActivityOptions.dispatchActivityStopped(); 163 mCalledActivityOptions = null; 164 } 165 if (mEnterTransitionCoordinator != null) { 166 mEnterTransitionCoordinator.stop(); 167 mEnterTransitionCoordinator = null; 168 } 169 } 170 171 public boolean startExitBackTransition(Activity activity) { 172 if (mEnteringNames == null) { 173 return false; 174 } else { 175 if (!mHasExited) { 176 mHasExited = true; 177 if (mEnterTransitionCoordinator != null) { 178 mEnterTransitionCoordinator.stop(); 179 mEnterTransitionCoordinator = null; 180 } 181 ArrayMap<String, View> sharedElements = new ArrayMap<String, View>(); 182 activity.getWindow().getDecorView().findNamedViews(sharedElements); 183 184 ExitTransitionCoordinator exitCoordinator = 185 new ExitTransitionCoordinator(activity, mEnteringNames, mEnteringFrom, 186 mEnteringTo, true); 187 exitCoordinator.startExit(activity.mResultCode, activity.mResultData); 188 } 189 return true; 190 } 191 } 192 193 public void startExitOutTransition(Activity activity, Bundle options) { 194 if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) { 195 return; 196 } 197 mCalledActivityOptions = new ActivityOptions(options); 198 if (mCalledActivityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) { 199 mExitingFrom = mCalledActivityOptions.getSharedElementNames(); 200 mExitingTo = mCalledActivityOptions.getLocalSharedElementNames(); 201 mCalledActivityOptions.dispatchStartExit(); 202 } 203 } 204} 205