主题
SpinKit
30 个基于 Flutter 的 flutter_spinkit 包构建的动画加载指示器控件。
用法
把 flet-spinkit 添加到项目依赖中:
uv
bash
uv add flet-spinkitpip
bash
pip install flet-spinkit [^1][^1]: 之后你需要手动把这个包添加到 requirements.txt 或 pyproject.toml 中。
然后在你的 Flet 应用中导入该包:
python
import flet_spinkit as spins启动屏
flet-spinkit 还提供了一个名为 spinkit 的启动屏 —— 一个在打包应用启动期间显示的动画加载器。把 flet-spinkit 设为依赖后,在 pyproject.toml 中选择它:
toml
[tool.flet.boot_screen]
name = "spinkit"
[tool.flet.boot_screen.spinkit]
spinner = "WanderingCubes" # any SpinKit animation (without the "SpinKit" prefix)
spinner_color_light = "#7c4dff"
spinner_color_dark = "#b388ff"
spinner_size = 60
bgcolor_light = "#ffffff"
bgcolor_dark = "#0d0d12"
prepare_message = "Preparing your app…"
startup_message = "Starting up…"所有选项都是可选的:
| 选项 | 默认值 | 说明 |
|---|---|---|
spinner | WanderingCubes | 任意 SpinKit 动画,命名时去掉 SpinKit 前缀(例如 Wave、FadingCube、PouringHourGlass)。不区分大小写。 |
theme_mode | auto | auto(跟随设备)、light 或 dark。 |
bgcolor_light / bgcolor_dark | Flet theme background | 背景色。 |
spinner_color_light / spinner_color_dark | Flet theme primary | 指示器颜色。 |
spinner_size | 60 | 指示器的尺寸(逻辑像素)。 |
text_color_light / text_color_dark | Flet theme on-surface | 消息文本颜色。 |
prepare_message | none | 解包应用期间显示的文本(仅 Android)。 |
startup_message | none | Python 运行时和应用启动期间显示的文本。 |
fade_out_duration | 0 | 应用就绪时的淡出时长(毫秒);0 表示立即移除。 |
TIP
这个启动屏是 createBootScreen 扩展钩子一个完整、真实的示例 —— 它的源码位于 flet-spinkit 的 src/flutter/flet_spinkit/lib/src/boot_screen.dart 中。
示例
python
import flet_spinkit as spins
import flet as ft
SPINNERS = [
("RotatingPlain", spins.RotatingPlain),
("DoubleBounce", spins.DoubleBounce),
("Wave", spins.Wave),
("WanderingCubes", spins.WanderingCubes),
("FadingFour", spins.FadingFour),
("FadingCube", spins.FadingCube),
("Pulse", spins.Pulse),
("ChasingDots", spins.ChasingDots),
("ThreeBounce", spins.ThreeBounce),
("Circle", spins.Circle),
("CubeGrid", spins.CubeGrid),
("FadingCircle", spins.FadingCircle),
("RotatingCircle", spins.RotatingCircle),
("FoldingCube", spins.FoldingCube),
("PumpingHeart", spins.PumpingHeart),
("HourGlass", spins.HourGlass),
("PouringHourGlass", spins.PouringHourGlass),
("PouringHourGlassRefined", spins.PouringHourGlassRefined),
("FadingGrid", spins.FadingGrid),
("Ring", spins.Ring),
("Ripple", spins.Ripple),
("DualRing", spins.DualRing),
("SpinningCircle", spins.SpinningCircle),
("SpinningLines", spins.SpinningLines),
("SquareCircle", spins.SquareCircle),
("ThreeInOut", spins.ThreeInOut),
("DancingSquare", spins.DancingSquare),
("PianoWave", spins.PianoWave),
("PulsingGrid", spins.PulsingGrid),
("WaveSpinner", spins.WaveSpinner),
]
def main(page: ft.Page):
page.title = "SpinKit Showcase"
page.scroll = ft.ScrollMode.AUTO
page.padding = 20
color = ft.Colors.BLUE
page.add(
ft.GridView(
runs_count=4,
max_extent=160,
child_aspect_ratio=0.9,
spacing=12,
run_spacing=12,
controls=[
ft.Container(
content=ft.Column(
[
ft.Container(
content=cls(color=color, size=50),
alignment=ft.Alignment.CENTER,
expand=True,
),
ft.Text(
name,
size=11,
text_align=ft.TextAlign.CENTER,
),
],
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
spacing=8,
),
bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST,
border_radius=12,
padding=12,
)
for name, cls in SPINNERS
],
)
)
if __name__ == "__main__":
ft.run(main)python
import flet_spinkit as spins
import flet as ft
def section(title: str, controls: list) -> ft.Column:
return ft.Column(
[
ft.Text(title, size=14, weight=ft.FontWeight.BOLD),
ft.Row(controls, spacing=24, wrap=True),
],
spacing=12,
)
def labeled(spinner, label: str) -> ft.Column:
return ft.Column(
[
ft.Container(
content=spinner,
alignment=ft.Alignment.CENTER,
width=80,
height=80,
),
ft.Text(
label,
size=10,
text_align=ft.TextAlign.CENTER,
),
],
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
spacing=4,
)
def main(page: ft.Page):
page.title = "SpinKit Properties"
page.scroll = ft.ScrollMode.AUTO
page.padding = 24
page.add(
ft.Text("SpinKit Properties", size=24, weight=ft.FontWeight.BOLD),
ft.Divider(height=16, color=ft.Colors.TRANSPARENT),
# Colors
section(
"color",
[
labeled(spins.RotatingCircle(color=ft.Colors.BLUE, size=50), "BLUE"),
labeled(spins.RotatingCircle(color=ft.Colors.RED, size=50), "RED"),
labeled(spins.RotatingCircle(color=ft.Colors.GREEN, size=50), "GREEN"),
labeled(
spins.RotatingCircle(color=ft.Colors.ORANGE, size=50), "ORANGE"
),
labeled(
spins.RotatingCircle(color=ft.Colors.PURPLE, size=50), "PURPLE"
),
labeled(spins.RotatingCircle(color=ft.Colors.TEAL, size=50), "TEAL"),
],
),
ft.Divider(height=8),
# Sizes
section(
"size",
[
labeled(spins.ThreeBounce(color=ft.Colors.BLUE, size=20), "20"),
labeled(spins.ThreeBounce(color=ft.Colors.BLUE, size=30), "30"),
labeled(spins.ThreeBounce(color=ft.Colors.BLUE, size=40), "40"),
labeled(spins.ThreeBounce(color=ft.Colors.BLUE, size=50), "50"),
labeled(spins.ThreeBounce(color=ft.Colors.BLUE, size=70), "70"),
],
),
ft.Divider(height=8),
# Durations
section(
"duration",
[
labeled(
spins.Pulse(
color=ft.Colors.BLUE,
size=50,
duration=ft.Duration(milliseconds=400),
),
"400ms",
),
labeled(
spins.Pulse(
color=ft.Colors.BLUE,
size=50,
duration=ft.Duration(milliseconds=700),
),
"700ms",
),
labeled(
spins.Pulse(
color=ft.Colors.BLUE,
size=50,
duration=ft.Duration(milliseconds=1000),
),
"1000ms",
),
labeled(
spins.Pulse(
color=ft.Colors.BLUE,
size=50,
duration=ft.Duration(milliseconds=2000),
),
"2000ms",
),
labeled(
spins.Pulse(
color=ft.Colors.BLUE,
size=50,
duration=ft.Duration(milliseconds=4000),
),
"4000ms",
),
],
),
ft.Divider(height=8),
# Wave — wave_type
section(
"Wave · wave_type",
[
labeled(
spins.Wave(
color=ft.Colors.BLUE, size=50, wave_type=spins.WaveType.START
),
"START",
),
labeled(
spins.Wave(
color=ft.Colors.BLUE, size=50, wave_type=spins.WaveType.CENTER
),
"CENTER",
),
labeled(
spins.Wave(
color=ft.Colors.BLUE, size=50, wave_type=spins.WaveType.END
),
"END",
),
],
),
ft.Divider(height=8),
# Wave — item_count
section(
"Wave · item_count",
[
labeled(spins.Wave(color=ft.Colors.BLUE, size=50, item_count=3), "3"),
labeled(spins.Wave(color=ft.Colors.BLUE, size=50, item_count=5), "5"),
labeled(spins.Wave(color=ft.Colors.BLUE, size=50, item_count=7), "7"),
labeled(spins.Wave(color=ft.Colors.BLUE, size=50, item_count=10), "10"),
],
),
ft.Divider(height=8),
# Ring — line_width
section(
"Ring · line_width",
[
labeled(spins.Ring(color=ft.Colors.BLUE, size=50, line_width=2), "2"),
labeled(spins.Ring(color=ft.Colors.BLUE, size=50, line_width=5), "5"),
labeled(spins.Ring(color=ft.Colors.BLUE, size=50, line_width=8), "8"),
labeled(spins.Ring(color=ft.Colors.BLUE, size=50, line_width=12), "12"),
],
),
ft.Divider(height=8),
# DualRing — line_width
section(
"DualRing · line_width",
[
labeled(
spins.DualRing(color=ft.Colors.BLUE, size=50, line_width=2), "2"
),
labeled(
spins.DualRing(color=ft.Colors.BLUE, size=50, line_width=5), "5"
),
labeled(
spins.DualRing(color=ft.Colors.BLUE, size=50, line_width=8), "8"
),
labeled(
spins.DualRing(color=ft.Colors.BLUE, size=50, line_width=12), "12"
),
],
),
ft.Divider(height=8),
# Ripple — border_width
section(
"Ripple · border_width",
[
labeled(
spins.Ripple(color=ft.Colors.BLUE, size=50, border_width=2), "2"
),
labeled(
spins.Ripple(color=ft.Colors.BLUE, size=50, border_width=4), "4"
),
labeled(
spins.Ripple(color=ft.Colors.BLUE, size=50, border_width=8), "8"
),
labeled(
spins.Ripple(color=ft.Colors.BLUE, size=50, border_width=14), "14"
),
],
),
ft.Divider(height=8),
# SpinningLines — line_width
section(
"SpinningLines · line_width",
[
labeled(
spins.SpinningLines(color=ft.Colors.BLUE, size=50, line_width=1),
"1",
),
labeled(
spins.SpinningLines(color=ft.Colors.BLUE, size=50, line_width=2),
"2",
),
labeled(
spins.SpinningLines(color=ft.Colors.BLUE, size=50, line_width=4),
"4",
),
labeled(
spins.SpinningLines(color=ft.Colors.BLUE, size=50, line_width=6),
"6",
),
],
),
ft.Divider(height=8),
# PianoWave — item_count
section(
"PianoWave · item_count",
[
labeled(
spins.PianoWave(color=ft.Colors.BLUE, size=50, item_count=3), "3"
),
labeled(
spins.PianoWave(color=ft.Colors.BLUE, size=50, item_count=5), "5"
),
labeled(
spins.PianoWave(color=ft.Colors.BLUE, size=50, item_count=8), "8"
),
labeled(
spins.PianoWave(color=ft.Colors.BLUE, size=50, item_count=12), "12"
),
],
),
)
if __name__ == "__main__":
ft.run(main)可用的控件
- ChasingDots
- Circle
- CubeGrid
- DancingSquare
- DoubleBounce
- DualRing
- FadingCircle
- FadingCube
- FadingFour
- FadingGrid
- FoldingCube
- HourGlass
- PianoWave
- PouringHourGlass
- PouringHourGlassRefined
- Pulse
- PulsingGrid
- PumpingHeart
- Ring
- Ripple
- RotatingCircle
- RotatingPlain
- SpinningCircle
- SpinningLines
- SquareCircle
- ThreeBounce
- ThreeInOut
- WanderingCubes
- Wave
- WaveSpinner