Stylianos Gakis
08/24/2021, 9:05 PMState<T>
or just T
. An example from “Crane” the official android samples inside thread 🧵@Composable
private fun tintPeopleUserInput(
transitionState: MutableTransitionState<PeopleUserInputAnimationState>
): State<Color> {
val validColor = MaterialTheme.colors.onSurface
val invalidColor = MaterialTheme.colors.secondary
val transition = updateTransition(transitionState)
return transition.animateColor(
transitionSpec = { tween(durationMillis = 300) }
) {
if (it == Valid) validColor else invalidColor
}
}
Now as I understand it, Compose is smart enough to just handle it perfectly fine if the function looked like this instead
@Composable
private fun tintPeopleUserInput(
transitionState: MutableTransitionState<PeopleUserInputAnimationState>
): Color {
val validColor = MaterialTheme.colors.onSurface
val invalidColor = MaterialTheme.colors.secondary
val transition = updateTransition(transitionState, label = "")
val color by transition.animateColor(
transitionSpec = { tween(durationMillis = 300) }, label = ""
) {
if (it == Valid) validColor else invalidColor
}
return color
}
So why would one ever chose one over the other? If they are functionally equivalent, it feels like the simple non-state return type should be preferable? Are there any guidelines on this?Zach Klippenstein (he/him) [MOD]
08/24/2021, 9:09 PMState
, this function allows the caller to determine where to read the animated state, and thus how much/what to recompose/reexecute on each frame.State
inside a drawBehind
call, which means that each animation frame of this transition would only trigger a new draw pass, not a whole recomposition.corneil
08/24/2021, 9:09 PMStylianos Gakis
08/24/2021, 9:14 PMZach Klippenstein (he/him) [MOD]
08/24/2021, 9:15 PMdirectly on the top of the calling functionI’m not sure what you mean by this, but I think you’ve probably got the right idea
State
, the function doesn’t force that to be the only option – it leaves it up to the callerStylianos Gakis
08/24/2021, 9:21 PMColumn {
val transitionState = remember { peopleState.animationState }
val tint: Color = tintPeopleUserInput(transitionState) // here
val people = peopleState.people
CraneUserInput(
text = ...,
vectorImageId = ...,
tint = tint,
onClick = {}
)
if (transitionState.targetState == Invalid) {
Text(...)
}
}
The whole CraneUserInput and whatever else was included inside this Column (and outside of it, since it’s inline) would recompose instead of only whatever uses tint inside the CraneUserInput.
Would this be the case?Zach Klippenstein (he/him) [MOD]
08/24/2021, 9:31 PMtintPeopleUserInput
returned just T
instead of State<T>
, correctStylianos Gakis
08/24/2021, 9:33 PMZach Klippenstein (he/him) [MOD]
08/24/2021, 9:35 PM