@@ -11,6 +11,7 @@ import androidx.compose.key
1111import androidx.compose.remember
1212import androidx.compose.state
1313import androidx.ui.animation.animatedFloat
14+ import androidx.ui.core.AnimationClockAmbient
1415import androidx.ui.core.ContextAmbient
1516import androidx.ui.core.Modifier
1617import androidx.ui.core.drawClip
@@ -103,6 +104,10 @@ private val DefaultBackstackAnimation: AnimationBuilder<Float>
103104 * @param animationBuilder Defines the curve and speed of transition animations.
104105 * @param onTransitionStarting Callback that will be invoked before starting each transition.
105106 * @param onTransitionFinished Callback that will be invoked after each transition finishes.
107+ * @param inspectionParams Optional [InspectionParams] that, when not null, enables inspection mode,
108+ * which will draw all the screens in the backstack as a translucent 3D stack. You can wrap your
109+ * backstack with [InspectionGestureDetector] to automatically generate [InspectionParams]
110+ * controlled by touch gestures.
106111 * @param drawScreen Called with each element of [backstack] to render it.
107112 */
108113@Composable
@@ -113,6 +118,7 @@ fun <T : Any> Backstack(
113118 animationBuilder : AnimationBuilder <Float >? = null,
114119 onTransitionStarting : ((from: List <T >, to: List <T >, TransitionDirection ) -> Unit )? = null,
115120 onTransitionFinished : (() -> Unit )? = null,
121+ inspectionParams : InspectionParams ? = null,
116122 drawScreen : @Composable() (T ) -> Unit
117123) {
118124 require(backstack.isNotEmpty()) { " Backstack must contain at least 1 screen." }
@@ -143,6 +149,9 @@ fun <T : Any> Backstack(
143149 }
144150 }
145151 val animation = animationBuilder ? : DefaultBackstackAnimation
152+ val clock = AnimationClockAmbient .current
153+ val inspector = remember { BackstackInspector (clock) }
154+ inspector.params = inspectionParams
146155
147156 if (direction == null && activeKeys != backstack) {
148157 // Not in the middle of a transition and we got a new backstack.
@@ -201,19 +210,14 @@ fun <T : Any> Backstack(
201210 // state as soon as a different branch is taken. See @Pivotal for more information.
202211 activeStackDrawers = remember(activeKeys, transition) {
203212 activeKeys.mapIndexed { index, key ->
204- val isTop = index == activeKeys.size - 1
205213 ScreenWrapper (key) { progress, children ->
206- val visibility = when {
207- // transitionProgress always corresponds directly to visibility of the top screen.
208- isTop -> progress
209- // The second-to-top screen has the inverse visibility of the top screen.
210- index == activeKeys.size - 2 -> 1f - progress
211- // All other screens should not be drawn at all. They're only kept around to maintain
212- // their composable state.
213- else -> 0f
214+ // Inspector and transition are mutually exclusive.
215+ val screenModifier = if (inspector.isInspectionActive) {
216+ calculateInspectionModifier(inspector, index, activeKeys.size, progress)
217+ } else {
218+ calculateRegularModifier(transition, index, activeKeys.size, progress)
214219 }
215- val transitionModifier = transition.modifierForScreen(visibility, isTop)
216- Box (transitionModifier, children = children)
220+ Box (screenModifier, children = children)
217221 }
218222 }
219223 }
@@ -238,3 +242,36 @@ fun <T : Any> Backstack(
238242 }
239243 }
240244}
245+
246+ private fun calculateRegularModifier (
247+ transition : BackstackTransition ,
248+ index : Int ,
249+ count : Int ,
250+ progress : Float
251+ ): Modifier {
252+ val visibility = when (index) {
253+ // transitionProgress always corresponds directly to visibility of the top screen.
254+ count - 1 -> progress
255+ // The second-to-top screen has the inverse visibility of the top screen.
256+ count - 2 -> 1f - progress
257+ // All other screens should not be drawn at all. They're only kept around to maintain
258+ // their composable state.
259+ else -> 0f
260+ }
261+ return transition.modifierForScreen(visibility, index == count - 1 )
262+ }
263+
264+ @Composable
265+ private fun calculateInspectionModifier (
266+ inspector : BackstackInspector ,
267+ index : Int ,
268+ count : Int ,
269+ progress : Float
270+ ): Modifier {
271+ val visibility = when (index) {
272+ count - 1 -> progress
273+ // All previous screens are always visible in inspection mode.
274+ else -> 1f
275+ }
276+ return inspector.inspectScreen(index, count, visibility)
277+ }
0 commit comments