FullyLoadedTransition
@Sampled
@Composable
fun FullyLoadedTransition() {
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))
}
}
AnimatedVisibilityWithBooleanVisibleParamNoReceiver
@Sampled
@Composable
fun AnimatedVisibilityWithBooleanVisibleParamNoReceiver() {
var visible by remember { mutableStateOf(true) }
Box(modifier = Modifier.clickable { visible = !visible }) {
AnimatedVisibility(
visible = visible,
modifier = Modifier.align(Alignment.Center),
enter = fadeIn(),
exit = fadeOut(animationSpec = tween(200)) + scaleOut(),
) { // Content that needs to appear/disappear goes here:
// Here we can optionally define a custom enter/exit animation by creating an animation
// using the Transition<EnterExitState> object from AnimatedVisibilityScope:
// As a part of the enter transition, the corner radius will be animated from 0.dp to
// 50.dp.
val cornerRadius by
transition.animateDp {
when (it) {
EnterExitState.PreEnter -> 0.dp
EnterExitState.Visible -> 50.dp
// No corner radius change when exiting.
EnterExitState.PostExit -> 50.dp
}
}
Box(
Modifier.background(Color.Red, shape = RoundedCornerShape(cornerRadius))
.height(100.dp)
.fillMaxWidth()
)
}
}
}
ColumnAnimatedVisibilitySample
@Sampled
@Composable
fun ColumnAnimatedVisibilitySample() {
var itemIndex by remember { mutableStateOf(0) }
val colors = listOf(Color.Red, Color.Green, Color.Blue)
Column(Modifier.fillMaxWidth().clickable { itemIndex = (itemIndex + 1) % colors.size }) {
colors.forEachIndexed { i, color ->
// By default ColumnScope.AnimatedVisibility expands and shrinks new content while
// fading.
AnimatedVisibility(i <= itemIndex) {
Box(Modifier.requiredHeight(40.dp).fillMaxWidth().background(color))
}
}
}
}
AnimatedVisibilityLazyColumnSample
@Sampled
@Composable
fun AnimatedVisibilityLazyColumnSample() {
val turquoiseColors =
listOf(
Color(0xff07688C),
Color(0xff1986AF),
Color(0xff50B6CD),
Color(0xffBCF8FF),
Color(0xff8AEAE9),
Color(0xff46CECA),
)
// MyModel class handles the data change of the items that are displayed in LazyColumn.
class MyModel {
private val _items: MutableList<ColoredItem> = mutableStateListOf()
private var lastItemId = 0
val items: List<ColoredItem> = _items
// Each item has a MutableTransitionState field to track as well as to mutate the item's
// visibility. When the MutableTransitionState's targetState changes, corresponding
// transition will be fired. MutableTransitionState allows animation lifecycle to be
// observed through it's [currentState] and [isIdle]. See below for details.
inner class ColoredItem(val visible: MutableTransitionState<Boolean>, val itemId: Int) {
val color: Color
get() = turquoiseColors.let { it[itemId % it.size] }
}
AVColumnScopeWithMutableTransitionState
@Sampled
@Composable
fun AVColumnScopeWithMutableTransitionState() {
var visible by remember { mutableStateOf(true) }
val colors = remember { listOf(Color(0xff2a9d8f), Color(0xffe9c46a), Color(0xfff4a261)) }
Column {
repeat(3) {
AnimatedVisibility(
visibleState =
remember {
// This sets up the initial state of the AnimatedVisibility to false to
// guarantee an initial enter transition. In contrast, initializing this
// as
// `MutableTransitionState(visible)` would result in no initial enter
// transition.
MutableTransitionState(initialState = false)
}
.apply {
// This changes the target state of the visible state. If it's different
// than
// the initial state, an enter/exit transition will be triggered.
targetState = visible
}
) { // Content that needs to appear/disappear goes here:
Box(Modifier.fillMaxWidth().height(100.dp).background(colors[it]))
}
}
}
}
AddAnimatedVisibilityToGenericTransitionSample
@Composable
@Sampled
fun AddAnimatedVisibilityToGenericTransitionSample() {