Animation Basics
Introductionβ
Within Litho, UI updates are performed by changing state or props on the Component Tree, instead of mutating the views directly. The animation framework adds transitions to components that are triggered when regenerating a tree.
It's important to avoid accessing the underlying view to add animations as these values will probably not be preserved.
Transitions can be used to animate view properties when they change between layouts, which is due to a state update or new props from the parent. When changes to a tree occur due to a new state, these changes happen immediately.
The following code and animation show a simple Component that renders a yellow square then aligns it to either the right or left edge of the screen, based on the value of toRight
:
override fun ComponentScope.render(): Component {
val toRight = useState { false }
return Column(
style = Style.margin(all = 10.dp).onClick { toRight.update { !it } },
alignItems = if (toRight.value) YogaAlign.FLEX_END else YogaAlign.FLEX_START) {
child(SolidColor.create(context).color(Color.YELLOW).widthDip(80f).heightDip(80f).build())
}
}
When the value of the state changes, the ComponentTree
is re-rendered, which makes the square appear to 'jump' from its previous position to the new one.
The following section shows how to replace this 'jump' with a transition animation.
Bounds transitionsβ
Transition.allLayout()
may cause unexpected transitions because it adds transitions to ALL components present in the layout tree, which may include components higher than the target component in the hierarchy. Please use it carefully.
To add bounds animations to all transitioning components between tree changes, use the following:
useTransition(Transition.allLayout())
Transition.allLayout()
creates a transition that automatically animates any changes to position, width, or height, as shown in the following animation.
This method only works when changing the bounds of a component. It does not work with:
- Other properties, including scale, alpha, and rotation.
- Components being added or removed.
Transitionsβ
For greater control over the transitions, use the following APIs:
useTransition
- a hook that is used to define the transition animations. It accepts a Transition as its parameter.Transition
- a description of the Component/Property (mandatory) and how (optional) to animate it. Instead of using a Constructor to createTransition
instances, use one of the providedBuilder
s.transitionKey
- an identifier normally assigned to aComponent
that is to be animated. The key is then used when definingTransition
.AnimatedProperties
- used to target the property of aComponent
that should be animated when its value changes.
The following sample shows the APIs in use:
class AlphaTransitionKComponent : KComponent() {
override fun ComponentScope.render(): Component {
val isHalfAlpha = useState { false }
useTransition(Transition.create(SQUARE_KEY).animate(AnimatedProperties.ALPHA))
return Column(style = Style.onClick { isHalfAlpha.update { !it } }) {
child(
Row(
style =
Style.transitionKey(context, SQUARE_KEY, Transition.TransitionKeyType.GLOBAL)
.backgroundColor(Color.YELLOW)
.width(80.dp)
.height(80.dp)
.alpha(if (isHalfAlpha.value) 0.5f else 1.0f)))
}
}
}
The above code features the following:
transitionKey
- assigned to the component using theStyle.transitionKey
method.Transition
- created usingTransition.create()
that takes atransitionKey
and specifies the property of the component using the.animate()
method, which takesAnimatedProperties
. Both of these methods take a variable number of arguments, which means multipleTransition
s may be expressed as follows:
private const val SQUARE_KEY: String = "square"
private const val OVAL_KEY: String = "oval"
private const val ANOTHER_SHAPE: String = "another_shape"
// ...
useTransition(
Transition.create(SQUARE_KEY, OVAL_KEY, ANOTHER_SHAPE)
.animate(AnimatedProperties.X, AnimatedProperties.Y))
The following animation shows the AlphaTransitionComponent
in action.
The transitions animations API supports three types of transitions: Change, Appear and Disappear, which work differently depending on how the tree changes between states. The example in this page uses a Change transition.