This page is dedicated to the world of Compose Animations!
This section covers the important stuff about animations in Compose.
The way to add animations to a single value!
varenabledbyremember{mutableStateOf(true)} valanimatedAlpha:FloatbyanimateFloatAsState(if(enabled)1felse0.5f,label="alpha") Box(Modifier.fillMaxSize().graphicsLayer{alpha=animatedAlpha}.background(Color.Red))
For animating properties at the same time!
enumclassBoxState{Collapsed,Expanded} varcurrentStatebyremember{mutableStateOf(BoxState.Collapsed)} valtransition=updateTransition(currentState,label="box state") valrectbytransition.animateRect(label="rectangle"){state->when(state){BoxState.Collapsed->Rect(0f,0f,100f,100f)BoxState.Expanded->Rect(100f,100f,300f,300f)}} valborderWidthbytransition.animateDp(label="border width"){state->when(state){BoxState.Collapsed->1.dpBoxState.Expanded->0.dp}}
ways to handle visibility transitions.
varselectedbyremember{mutableStateOf(false)} valtransition=updateTransition(selected,label="selected state") valborderColorbytransition.animateColor(label="border color"){isSelected->if(isSelected)Color.MagentaelseColor.White} valelevationbytransition.animateDp(label="elevation"){isSelected->if(isSelected)10.dpelse2.dp} Surface(onClick={selected=!selected},shape=RoundedCornerShape(8.dp),border=BorderStroke(2.dp,borderColor),shadowElevation=elevation){Column(modifier=Modifier.fillMaxWidth().padding(16.dp)){Text(text="Hello, world!")// AnimatedVisibility as a part of the transition.transition.AnimatedVisibility(visible={targetSelected->targetSelected},enter=expandVertically(),exit=shrinkVertically()){Text(text="It is fine today.")}// AnimatedContent as a part of the transition.transition.AnimatedContent{targetState->if(targetState){Text(text="Selected")}else{Icon(imageVector=Icons.Default.Phone,contentDescription="Phone")}}}
for complex animation.
enumclassBoxState{Collapsed,Expanded}@ComposablefunAnimatingBox(boxState:BoxState){valtransitionData=updateTransitionData(boxState)// UI treeBox(modifier=Modifier.background(transitionData.color).size(transitionData.size))}// Holds the animation values.privateclassTransitionData(color:State,size:State ){valcolorbycolorvalsizebysize}// Create a Transition and return its animation values.@ComposableprivatefunupdateTransitionData(boxState:BoxState):TransitionData{valtransition=updateTransition(boxState,label="box state")valcolor=transition.animateColor(label="color"){state->when(state){BoxState.Collapsed->Color.GrayBoxState.Expanded->Color.Red}}valsize=transition.animateDp(label="size"){state->when(state){BoxState.Collapsed->64.dpBoxState.Expanded->128.dp}}returnremember(transition){TransitionData(color,size)}}
For animations.
valinfiniteTransition=rememberInfiniteTransition(label="infinite") valcolorbyinfiniteTransition.animateColor(initialValue=Color.Red,targetValue=Color.Green,animationSpec=infiniteRepeatable(animation=tween(1000,easing=LinearEasing),repeatMode=RepeatMode.Reverse),label="color") Box(Modifier.fillMaxSize().background(color))
API.
// Start out gray and animate to green/red based on `ok` valcolor=remember{Animatable(Color.Gray)} LaunchedEffect(ok){color.animateTo(if(ok)Color.GreenelseColor.Red)} Box(Modifier.fillMaxSize().background(color.value))
of animations.
valanim=remember{TargetBasedAnimation(animationSpec=tween(200),typeConverter=Float.VectorConverter,initialValue=200f,targetValue=1000f)} varplayTimebyremember{mutableLongStateOf(0L)} LaunchedEffect(anim){valstartTime=withFrameNanos{it}do{playTime=withFrameNanos{it}-startTimevalanimationValue=anim.getValueFromNanos(playTime)}while(someCustomCondition())}