blob: cf3eadb584e46f47bfff4add9850296cc67a29d1 [file] [log] [blame]
Chet Haasefaebd8f2012-05-18 14:17:57 -07001/*
2 * Copyright (C) 2013 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 */
Chet Haase6ebe3de2013-06-17 16:50:50 -070016
Chet Haasefaebd8f2012-05-18 14:17:57 -070017package android.view.transition;
18
19import android.content.Context;
20import android.view.LayoutInflater;
21import android.view.ViewGroup;
22
23/**
24 * A scene represents the collection of values that various properties in the
25 * View hierarchy will have when the scene is applied. A Scene can be
26 * configured to automatically run a Transition when it is applied, which will
27 * animate the various property changes that take place during the
28 * scene change.
29 */
30public final class Scene {
31
32 private Context mContext;
33 private int mLayoutId = -1;
34 private ViewGroup mSceneRoot;
35 private ViewGroup mLayout; // alternative to layoutId
36 Runnable mEnterAction, mExitAction;
37
38 /**
39 * Constructs a Scene with no information about how values will change
40 * when this scene is applied. This constructor might be used when
41 * a Scene is created with the intention of being dynamically configured,
42 * through setting {@link #setEnterAction(Runnable)} and possibly
43 * {@link #setExitAction(Runnable)}.
44 *
45 * @param sceneRoot The root of the hierarchy in which scene changes
46 * and transitions will take place.
47 */
48 public Scene(ViewGroup sceneRoot) {
49 mSceneRoot = sceneRoot;
50 }
51
52 /**
53 * Constructs a Scene which, when entered, will remove any
54 * children from the sceneRoot container and will inflate and add
55 * the hierarchy specified by the layoutId resource file.
56 *
57 * @param sceneRoot The root of the hierarchy in which scene changes
58 * and transitions will take place.
59 * @param layoutId The id of a resource file that defines the view
60 * hierarchy of this scene.
61 * @param context The context used in the process of inflating
62 * the layout resource.
63 */
64 public Scene(ViewGroup sceneRoot, int layoutId, Context context) {
65 mContext = context;
66 mSceneRoot = sceneRoot;
67 mLayoutId = layoutId;
68 }
69
70 /**
71 * Constructs a Scene which, when entered, will remove any
72 * children from the sceneRoot container and add the layout
73 * object as a new child of that container.
74 *
75 * @param sceneRoot The root of the hierarchy in which scene changes
76 * and transitions will take place.
77 * @param layout The view hiearrchy of this scene, added as a child
78 * of sceneRoot when this scene is entered.
79 */
80 public Scene(ViewGroup sceneRoot, ViewGroup layout) {
81 mSceneRoot = sceneRoot;
82 mLayout = layout;
83 }
84
85 /**
86 * Gets the root of the scene, which is the root of the view hierarchy
87 * affected by changes due to this scene, and which will be animated
88 * when this scene is entered.
89 *
90 * @return The root of the view hierarchy affected by this scene.
91 */
92 public ViewGroup getSceneRoot() {
93 return mSceneRoot;
94 }
95
96 /**
97 * Exits this scene, if it is the {@link ViewGroup#getCurrentScene()
98 * currentScene} on the scene's {@link #getSceneRoot() scene root}.
99 * Exiting a scene involves removing the layout added if the scene
100 * has either a layoutId or layout view group (set at construction
101 * time) and running the {@link #setExitAction(Runnable) exit action}
102 * if there is one.
103 */
104 public void exit() {
105 if (mSceneRoot.getCurrentScene() == this) {
106 if (mLayoutId >= 0 || mLayout != null) {
107 // Undo layout change caused by entering this scene
108 getSceneRoot().removeAllViews();
109 }
110 if (mExitAction != null) {
111 mExitAction.run();
112 }
113 }
114 }
115
116 /**
117 * Enters this scene, which entails changing all values that
118 * are specified by this scene. These may be values associated
119 * with a layout view group or layout resource file which will
120 * now be added to the scene root, or it may be values changed by
121 * an {@link #setEnterAction(Runnable)} enter action}, or a
122 * combination of the these. No transition will be run when the
123 * scene is entered. To get transition behavior in scene changes,
124 * use one of the methods in {@link TransitionManager} instead.
125 */
126 public void enter() {
127
128 // Apply layout change, if any
129 if (mLayoutId >= 0 || mLayout != null) {
130 // redundant with exit() action of previous scene, but must
131 // empty out that parent container before adding to it
132 getSceneRoot().removeAllViews();
133
134 if (mLayoutId >= 0) {
135 LayoutInflater.from(mContext).inflate(mLayoutId, mSceneRoot);
136 } else {
137 mSceneRoot.addView(mLayout);
138 }
139 }
140
141 // Notify next scene that it is entering. Subclasses may override to configure scene.
142 if (mEnterAction != null) {
143 mEnterAction.run();
144 }
145
146 mSceneRoot.setCurrentScene(this );
147 }
148
149 /**
150 * Scenes that are not defined with layout resources or
151 * hierarchies, or which need to perform additional steps
152 * after those hierarchies are changed to, should set an enter
153 * action, and possibly an exit action as well. An enter action
154 * will cause Scene to call back into application code to do
155 * anything else the application needs after transitions have
156 * captured pre-change values and after any other scene changes
157 * have been applied, such as the layout (if any) being added to
158 * the view hierarchy. After this method is called, Transitions will
159 * be played.
160 *
161 * @param action The runnable whose {@link Runnable#run() run()} method will
162 * be called when this scene is entered
163 * @see #setExitAction(Runnable)
164 * @see Scene#Scene(ViewGroup, int, Context)
165 * @see Scene#Scene(ViewGroup, ViewGroup)
166 */
167 public void setEnterAction(Runnable action) {
168 mEnterAction = action;
169 }
170
171 /**
172 * Scenes that are not defined with layout resources or
173 * hierarchies, or which need to perform additional steps
174 * after those hierarchies are changed to, should set an enter
175 * action, and possibly an exit action as well. An exit action
176 * will cause Scene to call back into application code to do
177 * anything the application needs to do after applicable transitions have
178 * captured pre-change values, but before any other scene changes
179 * have been applied, such as the new layout (if any) being added to
180 * the view hierarchy. After this method is called, the next scene
181 * will be entered, including a call to {@link #setEnterAction(Runnable)}
182 * if an enter action is set.
183 *
184 * @see #setEnterAction(Runnable)
185 * @see Scene#Scene(ViewGroup, int, Context)
186 * @see Scene#Scene(ViewGroup, ViewGroup)
187 */
188 public void setExitAction(Runnable action) {
189 mExitAction = action;
190 }
191
192}