Skip to content

HappyCoder256/flet-carousel-slider

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

flet_carousel_slider

A Flet custom control that wraps the powerful carousel_slider_plus Flutter package, bringing a fully featured image/content carousel to your Flet apps.


Features

  • Horizontal and vertical carousel sliding
  • Auto-play with configurable interval, duration, and curve
  • Infinite scroll
  • Center page enlargement with multiple strategies
  • Built-in dot indicator with active/inactive color control, scrollable with fade edges
  • Lazy (on-demand) or eager item building
  • Full programmatic control: animate_to, next, previous, jump_to
  • Python-side event callbacks: on_change, on_scrolled

Installation

Since this package is not yet published on PyPI, install it directly from the source:

# Clone the repository
git clone https://github.com/yourusername/flet_carousel_slider.git

# Install locally
pip install -e ./flet_carousel_slider

Once published to PyPI, installation will be:

pip install flet_carousel_slider

Basic Usage

import flet as ft
from flet_carousel_slider import *

def main(page: ft.Page):
    page.add(
        Carousel(
            controls=[
                ft.Image(src="https://picsum.photos/id/1/400/300", fit=ft.ImageFit.COVER),
                ft.Image(src="https://picsum.photos/id/2/400/300", fit=ft.ImageFit.COVER),
                ft.Image(src="https://picsum.photos/id/3/400/300", fit=ft.ImageFit.COVER),
            ],
            aspect_ratio=16 / 9,
            auto_play=True,
            enable_infinite_scroll=True,
            enable_indicator=True,
        )
    )

ft.app(main)

Programmatic Control

import flet as ft
from flet_carousel_slider import (
    Carousel,
    AnimateToCurve,
    EnlargeStrategy,
    ClipBehavior,
    ScrollDirection,
    CarouselPageChangedReason,
)

SLIDES = [
    ("🏔️ Mountains",  ft.Colors.BLUE_700),
    ("🌊 Ocean",       ft.Colors.CYAN_600),
    ("🌲 Forest",      ft.Colors.GREEN_700),
    ("🏜️ Desert",     ft.Colors.ORANGE_700),
    ("❄️ Arctic",      ft.Colors.INDIGO_300),
    ("🌋 Volcano",     ft.Colors.RED_700),
    ("🌲 Forest",      ft.Colors.GREEN_700),
    ("🏜️ Desert",     ft.Colors.ORANGE_700),
    ("❄️ Arctic",      ft.Colors.INDIGO_300),
    ("🌋 Volcano",     ft.Colors.RED_700),
    ("🌲 Forest",      ft.Colors.GREEN_700),
    ("🏜️ Desert",     ft.Colors.ORANGE_700),
    ("❄️ Arctic",      ft.Colors.INDIGO_300),
    ("🌋 Volcano",     ft.Colors.RED_700),
    ("🌲 Forest",      ft.Colors.GREEN_700),
    ("🏜️ Desert",     ft.Colors.ORANGE_700),
    ("❄️ Arctic",      ft.Colors.INDIGO_300),
    ("🌋 Volcano",     ft.Colors.RED_700),
]


def slide_card(label: str, color: str) -> ft.Container:
    return ft.Container(
        content=ft.Text(label, size=22, weight=ft.FontWeight.BOLD, color=ft.Colors.WHITE),
        bgcolor=color,
        border_radius=16,
        alignment=ft.alignment.center,
        margin=ft.margin.symmetric(horizontal=8),
    )


def main(page: ft.Page):
    page.title = "carousel_slider 5.1.2 – Flet demo"
    page.theme = ft.Theme(use_material3=True)
    page.padding = 20
    page.scroll = ft.ScrollMode.AUTO
    page.window.always_on_top = True
    # ── status log ────────────────────────────────────────────────────
    status = ft.Text("", size=13, italic=True, color=ft.Colors.GREY_700)

    def log(msg: str):
        status.value = msg
        page.update()

    # ── event handlers ────────────────────────────────────────────────
    def on_changed(e):
        reason_label = {
            CarouselPageChangedReason.TIMED:      "autoplay",
            CarouselPageChangedReason.MANUAL:     "swipe",
            CarouselPageChangedReason.CONTROLLER: "controller",
        }.get(e.reason, e.reason.value)
        log(f"on_change → index={e.index}  reason={reason_label}")

    def on_scrolled(e):
        # fires very frequently — only log every ~0.5 units to avoid spam
        if abs(e.value % 0.5) < 0.05:
            log(f"on_scrolled → {e.value:.2f}")

    # ── carousel ──────────────────────────────────────────────────────
    carousel = Carousel(
        controls=[slide_card(label, color) for label, color in SLIDES],
        # layout
        height=200,
        viewport_fraction=0.85,
        initial_page=0,
        # infinite / reverse
        enable_infinite_scroll=False,
        reverse=False,
        # autoplay
        auto_play=True,
        auto_play_interval=3000,
        auto_play_animation_duration=800,
        auto_play_curve=AnimateToCurve.FAST_OUT_SLOW_IN,
        pause_auto_play_on_touch=True,
        pause_auto_play_on_manual_navigate=True,
        pause_auto_play_in_finite_scroll=False,
        # enlarge
        enlarge_center_page=True,
        enlarge_strategy=EnlargeStrategy.SCALE,
        enlarge_factor=0.3,
        # misc
        page_snapping=True,
        animate_to_closest=True,
        disable_center=False,
        pad_ends=True,
        scroll_direction=ScrollDirection.HORIZONTAL,
        clip_behavior=ClipBehavior.HARD_EDGE,
        # events
        on_change=on_changed,
        on_scrolled=on_scrolled,
        disablegesture=False,
        build_on_demand=True,
        indicatorwidth=140,
        indicator_active_color="yellow",
        indicator_inactive_color="green"
    )

    # ── controller buttons ────────────────────────────────────────────
    def go_prev(e):
        carousel.previous_page(duration=400, curve=AnimateToCurve.EASE_IN_OUT)

    def go_next(e):
        carousel.next_page(duration=400, curve=AnimateToCurve.EASE_IN_OUT)

    def go_page_0(e):
        carousel.animate_to_page(0, duration=600, curve=AnimateToCurve.EASE_OUT)

    def go_page_3(e):
        carousel.animate_to_page(3, duration=600, curve=AnimateToCurve.BOUNCE_OUT)

    def jump_last(e):
        carousel.jump_to_page(len(SLIDES) - 1)

    def toggle_autoplay(e):
        carousel.auto_play = not carousel.auto_play
        btn_autoplay.text = (
            "⏸ Pause autoplay" if carousel.auto_play else "▶ Resume autoplay"
        )
        page.update()

    btn_autoplay = ft.ElevatedButton("⏸ Pause autoplay", on_click=toggle_autoplay)

    page.add(
        ft.Text("carousel_slider 5.1.2 – Flet", size=26, weight=ft.FontWeight.BOLD),
        ft.Container(content=carousel, height=220),
        ft.Divider(height=16),

        ft.Text("Controller methods", size=16, weight=ft.FontWeight.W_600),
        ft.Row([
            ft.ElevatedButton("◀ Prev",    on_click=go_prev),
            ft.ElevatedButton("Next ▶",    on_click=go_next),
            ft.ElevatedButton("→ Page 0",  on_click=go_page_0),
            ft.ElevatedButton("→ Page 3",  on_click=go_page_3),
            ft.ElevatedButton("Jump last", on_click=jump_last),
            btn_autoplay,
        ], wrap=True, spacing=8),

        ft.Divider(height=16),
        ft.Text("Events", size=16, weight=ft.FontWeight.W_600),
        status,
    )


ft.app(target=main)

Events

def on_slide_change(e):
    print(f"Slide changed: index={e.data}")

def on_slide_scrolled(e):
    print(f"Scroll position: {e.data}")

CarouselSlider(
    controls=[...],
    on_change=on_slide_change,
    on_scrolled=on_slide_scrolled,
)

Properties

Carousel

Property Type Default Description
controls List[Control] required The list of widgets to display as slides
height float None Fixed height of the carousel. If set, overrides aspect_ratio
aspect_ratio float 16/9 Aspect ratio used when height is not set
viewport_fraction float 0.8 Fraction of the viewport each slide occupies (e.g. 1.0 for full width)
initial_page int 0 The index of the slide shown on first load
enable_infinite_scroll bool True Whether the carousel loops infinitely
animate_to_closest bool True Whether to animate to the closest page on scroll end
reverse bool False Reverse the scroll direction
page_snapping bool True Snap to page boundaries on scroll end
scroll_direction str "horizontal" Scroll axis — "horizontal" or "vertical"
clip_behavior str "hardEdge" Flutter clip mode — "none", "hardEdge", "antiAlias", "antiAliasWithSaveLayer"
disable_gesture bool False Disable swipe gestures (useful when controlling programmatically only)
disable_center bool False Disable centering of slides
pad_ends bool True Add padding at the ends of the carousel
build_on_demand bool False Build slides lazily (on-demand) for better performance with large lists

Auto Play

Property Type Default Description
auto_play bool False Enable automatic sliding
auto_play_interval int 4000 Time in milliseconds between auto-play slides
auto_play_animation_duration int 800 Duration in milliseconds of the auto-play slide animation
auto_play_curve str "fastOutSlowIn" Animation curve for auto-play. See Curves
pause_auto_play_on_touch bool True Pause auto-play when the user touches the carousel
pause_auto_play_on_manual_navigate bool True Pause auto-play when navigating programmatically
pause_auto_play_in_finite_scroll bool False Pause auto-play at the ends when infinite scroll is disabled

Enlarge Center Page

Property Type Default Description
enlarge_center_page bool False Enlarge the center/active slide
enlarge_strategy str "scale" How the center page is enlarged — "scale", "height", "zoom"
enlarge_factor float 0.3 How much the center page is enlarged (0.0 to 1.0)

Indicator

Property Type Default Description
enable_indicator bool True Show dot indicators below the carousel
indicator_active_color ft.Colors theme default Color of the currently active dot
indicator_inactive_color ft.Colors theme default Color of the inactive dots
indicator_row_width float None Max width of the indicator row. If None, takes full available width

Events

Event Data Description
on_change "index:reason" Fired when the active slide changes. reason is one of timed, manual, controller
on_scrolled "0.0000" Fired continuously while scrolling with the current scroll offset

Programmatic Methods

Method Parameters Description
animate_to(index) index: int, duration: int = 300, curve: str = "fastOutSlowIn" Animate to a specific slide index
next() duration: int = 300, curve: str = "fastOutSlowIn" Go to the next slide
previous() duration: int = 300, curve: str = "fastOutSlowIn" Go to the previous slide
jump_to(index) index: int Jump to a slide instantly with no animation

Animation Curves

The following curve names are accepted by auto_play_curve and animation methods:

"linear", "easeIn", "easeOut", "easeInOut", "bounceIn", "bounceOut", "elasticIn", "elasticOut", "decelerate", "fastOutSlowIn"


Full Example

import flet as ft
from flet_carousel_slider import CarouselSlider

def main(page: ft.Page):
    page.padding = 0

    carousel = CarouselSlider(
        controls=[
            ft.Container(
                content=ft.Text(f"Slide {i+1}", size=30, color=ft.Colors.WHITE),
                bgcolor=[ft.Colors.BLUE, ft.Colors.RED, ft.Colors.GREEN, ft.Colors.ORANGE][i],
                alignment=ft.alignment.center,
                expand=True,
            )
            for i in range(4)
        ],
        aspect_ratio=16 / 9,
        auto_play=True,
        auto_play_interval=3000,
        auto_play_curve="easeInOut",
        enable_infinite_scroll=True,
        enlarge_center_page=True,
        enlarge_strategy="zoom",
        viewport_fraction=0.85,
        enable_indicator=True,
        indicator_active_color=ft.Colors.BLACK,
        indicator_inactive_color=ft.Colors.GREY,
        on_change=lambda e: print(f"Changed to: {e.data}"),
    )

    page.add(carousel)

ft.app(main)

License

MIT

About

A Flet based Carousel Slider based on The Flutter package Carousel_slider_plus

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors