Skip to content

Animated

PythonNative's Animated API mirrors React Native's. Build performant animations declaratively by binding AnimatedValue instances to the style of an Animated.View, Animated.Text, or Animated.Image. The reconciler holds a ref to the underlying native view; the animation driver pushes value changes directly to the native handler's set_animated_property hook so per-frame updates bypass full reconciliation.

Animated values, native-driven animation, and animated components.

Modeled on React Native's Animated API with an async-aware completion contract. The core primitives are:

  • AnimatedValue: a numeric cell attached to native view properties; animations drive it over time.
  • Animated.timing / Animated.spring / Animated.decay: animation factories. The objects they return implement __await__, so you can write await Animated.timing(v, to=1.0) to suspend until the animation finishes.
  • Animated.sequence / Animated.parallel / Animated.delay: composition; also awaitable.
  • Animated.View / Animated.Text / Animated.Image: components whose style may contain AnimatedValue instances.

Driver architecture (the native driver):

When an animation starts, PythonNative compiles its spec (curve, duration, target value) and offers it to the platform handler of every native view the value is attached to (ViewHandler.start_animation).

  • Accepted (iOS Core Animation, Android ViewPropertyAnimator / DynamicAnimation): the platform animates the property entirely natively; no Python code runs per frame. Python receives exactly one callback when the animation settles, updates the AnimatedValue, and resolves any awaiting tasks.
  • Declined (desktop preview, unattached values, callable easings, values feeding Python-side listeners): a single background thread ticks the animation at ~60 Hz from Python, pushing each frame through set_animated_property. Semantics are identical; only the frame source differs.
Example
import pythonnative as pn


@pn.component
def FadeIn():
    opacity = pn.use_animated_value(0.0)

    async def fade_in():
        await pn.Animated.timing(opacity, to=1.0, duration=400)
        await pn.Animated.timing(opacity, to=0.5, duration=200)

    pn.use_async_effect(fade_in, [])

    return pn.Animated.View(
        pn.Text("Hello!"),
        style={"opacity": opacity, "padding": 20},
    )

Classes:

Name Description
AnimatedValue

A numeric cell that can be attached to native view properties.

Functions:

Name Description
native_animation_completed

Report a natively-driven animation as settled.

use_animated_value

Return an AnimatedValue that is stable across renders.

Attributes:

Name Type Description
Animated

Animated module-attribute

Animated = _AnimatedNamespace()

AnimatedValue

AnimatedValue(initial: float = 0.0)

A numeric cell that can be attached to native view properties.

Animated components (Animated.View et al.) attach the value to (tag, prop) bindings after mount. Setting the value pushes the new number to every attached native view through the registry's set_animated_property, and when an animation can be driven natively, the platform animates those same bindings directly.

Python-side listeners registered via add_listener observe every Python-driven change. Natively-driven animations intentionally skip per-frame Python callbacks (that's the point); listeners see the final settled value.

Methods:

Name Description
set_value

Set the value immediately, pushing to native views and listeners.

attach

Bind this value to prop of the native view under tag.

attachments

Snapshot of the current (tag, prop) bindings.

add_listener

Register callback for Python-driven changes to this value.

has_listeners

Whether any Python-side listeners are registered.

stop_animation

Cancel any in-flight animation on this value (native or Python).

Attributes:

Name Type Description
value float

Return the current numeric value (without subscribing).

value property

value: float

Return the current numeric value (without subscribing).

set_value

set_value(new_value: float) -> None

Set the value immediately, pushing to native views and listeners.

attach

attach(tag: int, prop: str) -> Callable[[], None]

Bind this value to prop of the native view under tag.

The current value is pushed immediately so the view reflects it even if no animation is running. Returns a detach callable.

attachments

attachments() -> List[Tuple[int, str]]

Snapshot of the current (tag, prop) bindings.

add_listener

add_listener(prop: str, callback: Callable[[float], None]) -> Callable[[], None]

Register callback for Python-driven changes to this value.

Returns an unsubscribe callable. prop is metadata only; it lets the subscriber differentiate this binding from others on the same AnimatedValue.

has_listeners

has_listeners() -> bool

Whether any Python-side listeners are registered.

stop_animation

stop_animation() -> None

Cancel any in-flight animation on this value (native or Python).

native_animation_completed

native_animation_completed(anim_id: int, finished: bool = True) -> None

Report a natively-driven animation as settled.

Called by platform handlers from their completion callbacks (iOS UIView completion blocks, Android withEndAction / DynamicAnimation.OnAnimationEndListener). Safe to call from any thread; unknown ids are ignored (e.g. an animation cancelled moments before its completion fired).

Parameters:

Name Type Description Default
anim_id int

The id passed to ViewHandler.start_animation.

required
finished bool

False when the platform reports the animation was interrupted rather than running to completion.

True

use_animated_value

use_animated_value(initial: float = 0.0) -> AnimatedValue

Return an AnimatedValue that is stable across renders.

Convenience wrapper for the common pattern pn.use_memo(lambda: AnimatedValue(initial), []). The same instance is returned on every render of the same component, so you can drive it from event handlers without recreating it.

Parameters:

Name Type Description Default
initial float

The starting numeric value.

0.0

Returns:

Type Description
AnimatedValue

A mount-stable AnimatedValue.

Example
import pythonnative as pn


@pn.component
def FadeIn():
    opacity = pn.use_animated_value(0.0)

    async def fade_in():
        await pn.Animated.timing(opacity, to=1.0, duration=300)

    pn.use_async_effect(fade_in, [])
    return pn.Animated.View(
        pn.Text("Hello"),
        style=pn.style(opacity=opacity),
    )

See also

  • The Animations guide walks through fade-ins, springs, sequences, and gesture-driven animations.
  • use_ref explains the ref semantics that back Animated.View.