Skip to content

AnimatedSwitcher

Used to switch between controls with an animation.

Inherits: LayoutControl

Properties

Examples#

Live example

Animated switching between two containers with scale effect#

import flet as ft


def main(page: ft.Page):
    c1 = ft.Container(
        content=ft.Text("Hello!", theme_style=ft.TextThemeStyle.HEADLINE_MEDIUM),
        alignment=ft.Alignment.CENTER,
        width=200,
        height=200,
        bgcolor=ft.Colors.GREEN,
    )
    c2 = ft.Container(
        content=ft.Text("Bye!", size=50),
        alignment=ft.Alignment.CENTER,
        width=200,
        height=200,
        bgcolor=ft.Colors.YELLOW,
    )
    switcher = ft.AnimatedSwitcher(
        content=c1,
        transition=ft.AnimatedSwitcherTransition.SCALE,
        duration=500,
        reverse_duration=100,
        switch_in_curve=ft.AnimationCurve.BOUNCE_OUT,
        switch_out_curve=ft.AnimationCurve.BOUNCE_IN,
    )

    def scale(e):
        switcher.content = c2 if switcher.content == c1 else c1
        switcher.transition = ft.AnimatedSwitcherTransition.SCALE
        switcher.update()

    def fade(e):
        switcher.content = c2 if switcher.content == c1 else c1
        switcher.transition = ft.AnimatedSwitcherTransition.FADE
        switcher.update()

    def rotate(e):
        switcher.content = c2 if switcher.content == c1 else c1
        switcher.transition = ft.AnimatedSwitcherTransition.ROTATION
        switcher.update()

    page.add(
        switcher,
        ft.Button("Scale", on_click=scale),
        ft.Button("Fade", on_click=fade),
        ft.Button("Rotate", on_click=rotate),
    )


ft.run(main)

scale-effect

Animate Image switch#

import time

import flet as ft


def main(page: ft.Page):
    def animate(e: ft.Event[ft.Button]):
        switcher.content = ft.Image(
            src=f"https://picsum.photos/200/300?{time.time()}",
            width=200,
            height=300,
        )
        page.update()

    page.add(
        switcher := ft.AnimatedSwitcher(
            content=ft.Image(
                src="https://picsum.photos/200/300",
                width=200,
                height=300,
            ),
            transition=ft.AnimatedSwitcherTransition.SCALE,
            duration=500,
            reverse_duration=100,
            switch_in_curve=ft.AnimationCurve.BOUNCE_OUT,
            switch_out_curve=ft.AnimationCurve.BOUNCE_IN,
        ),
        ft.Button("Animate!", on_click=animate),
    )


ft.run(main)

Animate Image switch buffered#

import base64
import time

import httpx

import flet as ft


class BufferingSwitcher(ft.AnimatedSwitcher):
    image_queue = []

    def __init__(self, image: ft.Image, page: ft.Page):
        super().__init__(image)
        self.transition = ft.AnimatedSwitcherTransition.SCALE
        self.duration = 500
        self.reverse_duration = 100
        self.switch_in_curve = ft.AnimationCurve.EASE_IN
        self.switch_out_curve = ft.AnimationCurve.EASE_OUT
        self.image_queue.append(image)
        self.page = page

    def animate(self, e):
        self.content = ft.Image(
            src_base64=self.image_queue.pop(),
            width=200,
            height=300,
            gapless_playback=True,
        )
        self.update()

    async def fill_queue(self):
        while len(self.image_queue) < 10:
            self.image_queue.append(
                await self.image_to_base64(
                    f"https://picsum.photos/200/300?{time.time()}"
                )
            )

    async def image_to_base64(self, url):
        print("image_to_base64 called")
        response = await httpx.AsyncClient(follow_redirects=True).get(url)
        if response.status_code == 200:
            base64_str = (
                base64.standard_b64encode(response.content).decode("utf-8").strip()
            )
            return base64_str
        else:
            print(f"Image request failed with {response.status_code}")
            return None

    def before_update(self):
        self.page.run_task(self.fill_queue)
        print(len(self.image_queue))


def main(page: ft.Page):
    switcher = BufferingSwitcher(
        ft.Image(
            src=f"https://picsum.photos/200/300?{time.time()}", width=200, height=300
        ),
        page,
    )

    page.add(
        switcher,
        ft.Button("Animate!", on_click=switcher.animate),
    )


ft.run(main)

Properties#

content #

content: Control

The content to display.

When it changes, this switcher will animate the transition from the old/previous content to the new one.

Raises:

duration #

duration: DurationValue = field(
    default_factory=lambda: Duration(seconds=1)
)

The duration of the transition from the old content to the new one.

reverse_duration #

reverse_duration: DurationValue = field(
    default_factory=lambda: Duration(seconds=1)
)

The duration of the transition from the new content to the old one.

switch_in_curve #

switch_in_curve: AnimationCurve = LINEAR

The animation curve to use when transitioning in a new content.

switch_out_curve #

switch_out_curve: AnimationCurve = LINEAR

The animation curve to use when transitioning an old content out.

transition #

An animation type to transition between new and old content.