ExitTransition
-
Cmn
sealed class ExitTransition
ExitTransition defines how an AnimatedVisibility Composable disappears on screen as it becomes not visible. The 4 categories of ExitTransition available are:
-
fade:
fadeOut -
scale:
scaleOut -
shrink:
shrinkOut,shrinkHorizontally,shrinkVertically
ExitTransition.None can be used when no exit transition is desired. Different ExitTransitions can be combined using plus operator, for example:
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideIn import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOut import androidx.compose.animation.slideOutHorizontally import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.width import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = slideInHorizontally(animationSpec = tween(durationMillis = 200)) { fullWidth -> // Offsets the content by 1/3 of its width to the left, and slide towards right // Overwrites the default animation with tween for this slide animation. -fullWidth / 3 } + fadeIn( // Overwrites the default animation with tween animationSpec = tween(durationMillis = 200) ), exit = slideOutHorizontally(animationSpec = spring(stiffness = Spring.StiffnessHigh)) { // Overwrites the ending position of the slide-out to 200 (pixels) to the right 200 } + fadeOut(), ) { // Content that needs to appear/disappear goes here: Box(Modifier.fillMaxWidth().requiredHeight(200.dp)) {} }
Note: fadeOut and slideOut do not affect the size of the AnimatedVisibility composable. In contrast, shrinkOut (and shrinkHorizontally, shrinkVertically) will shrink the clip bounds to reveal less and less of the content. This will automatically animate other layouts to fill in the space, very much like animateContentSize.
| See also | |
|---|---|
fadeOut |
|
scaleOut |
|
slideOut |
|
slideOutHorizontally |
|
slideOutVertically |
|
shrinkOut |
|
shrinkHorizontally |
|
shrinkVertically |
|
AnimatedVisibility |
Summary
Public companion properties |
||
|---|---|---|
ExitTransition |
This can be used when no built-in |
Cmn
|
Protected constructors |
|
|---|---|
|
Cmn
|
Public functions |
||
|---|---|---|
open operator Boolean |
Cmn
|
|
open Int |
hashCode() |
Cmn
|
operator ExitTransition |
plus(exit: ExitTransition)Combines different exit transitions. |
Cmn
|
open String |
toString() |
Cmn
|
Public companion properties
None
val None: ExitTransition
This can be used when no built-in ExitTransition (i.e. fade/slide, etc) is desired for the AnimatedVisibility, but rather the children are defining their own exit animation using the Transition scope.
Note: If None is used, and nothing is animating in the TransitionAnimatedVisibility provided, the content will be removed from AnimatedVisibility right away.
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.EnterExitState import androidx.compose.animation.ExitTransition import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.core.MutableTransitionState import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.tween import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideIn import androidx.compose.animation.slideInVertically import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Button import androidx.compose.material.FloatingActionButton import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Favorite import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.unit.dp @OptIn(ExperimentalAnimationApi::class) @Composable fun AnimatedVisibilityScope.Item(modifier: Modifier, backgroundColor: Color) { // Creates a custom enter/exit animation for scale property. val scale by transition.animateFloat { enterExitState -> // Enter transition will be animating the scale from 0.9f to 1.0f // (i.e. PreEnter -> Visible). Exit transition will be from 1.0f to // 0.5f (i.e. Visible -> PostExit) when (enterExitState) { EnterExitState.PreEnter -> 0.9f EnterExitState.Visible -> 1.0f EnterExitState.PostExit -> 0.5f } } // Since we defined `Item` as an extension function on AnimatedVisibilityScope, we can use // the `animateEnterExit` modifier to produce an enter/exit animation for it. This will // run simultaneously with the `AnimatedVisibility`'s enter/exit. Box( modifier .fillMaxWidth() .padding(5.dp) .animateEnterExit( // Slide in from below, enter = slideInVertically(initialOffsetY = { it }), // No slide on the way out. So the exit animation will be scale (from the custom // scale animation defined above) and fade (from AnimatedVisibility) exit = ExitTransition.None, ) .graphicsLayer { scaleX = scale scaleY = scale } .clip(RoundedCornerShape(20.dp)) .background(backgroundColor) .fillMaxSize() ) { // Content of the item goes here... } } @Composable fun AnimateMainContent(mainContentVisible: MutableTransitionState<Boolean>) { Box { // Use the `MutableTransitionState<Boolean>` to specify whether AnimatedVisibility // should be visible. This will also allow AnimatedVisibility animation states to be // observed externally. AnimatedVisibility( visibleState = mainContentVisible, modifier = Modifier.fillMaxSize(), enter = fadeIn(), exit = fadeOut(), ) { Box { Column(Modifier.fillMaxSize()) { // We have created `Item`s below as extension functions on // AnimatedVisibilityScope in this example. So they can define their own // enter/exit to run alongside the enter/exit defined in AnimatedVisibility. Item(Modifier.weight(1f), backgroundColor = Color(0xffff6f69)) Item(Modifier.weight(1f), backgroundColor = Color(0xffffcc5c)) } // This FAB will be simply fading in/out as specified by the AnimatedVisibility FloatingActionButton( onClick = {}, modifier = Modifier.align(Alignment.BottomEnd).padding(20.dp), backgroundColor = MaterialTheme.colors.primary, ) { Icon(Icons.Default.Favorite, contentDescription = null) } } } // Here we can get a signal for when the Enter/Exit animation of the content above // has finished by inspecting the MutableTransitionState passed to the // AnimatedVisibility. This allows sequential animation after the enter/exit. AnimatedVisibility( // Once the main content is visible (i.e. targetState == true), and no pending // animations. We will start another enter animation sequentially. visible = mainContentVisible.targetState && mainContentVisible.isIdle, modifier = Modifier.align(Alignment.Center), enter = expandVertically(), exit = fadeOut(animationSpec = tween(50)), ) { Text("Transition Finished") } } }
Protected constructors
Public functions
plus
operator fun plus(exit: ExitTransition): ExitTransition
Combines different exit transitions. The order of the ExitTransitions being combined does not matter, as these ExitTransitions will start simultaneously. The order of applying transforms from these exit transitions (if defined) is: veil first, then alpha and scale, shrink or expand, then slide.
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleOut import androidx.compose.animation.shrinkVertically import androidx.compose.animation.slideIn import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOut import androidx.compose.animation.slideOutVertically import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.requiredHeight import androidx.compose.material.Text import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.unit.dp var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = slideInVertically( // Start the slide from 40 (pixels) above where the content is supposed to go, to // produce a parallax effect initialOffsetY = { -40 } ) + expandVertically(expandFrom = Alignment.Top) + scaleIn( // Animate scale from 0f to 1f using the top center as the pivot point. transformOrigin = TransformOrigin(0.5f, 0f) ) + fadeIn(initialAlpha = 0.3f), exit = slideOutVertically() + shrinkVertically() + fadeOut() + scaleOut(targetScale = 1.2f), ) { // Content that needs to appear/disappear goes here: Text("Content to appear/disappear", Modifier.fillMaxWidth().requiredHeight(200.dp)) }
| Parameters | |
|---|---|
exit: ExitTransition |
another |