Flet 隐式动画实战指南:用 Python 为控件添加 Opacity、Rotation、Scale、Offset 与 Position 动画

发布时间:2026/9/23 2:39:05
Flet 隐式动画实战指南:用 Python 为控件添加 Opacity、Rotation、Scale、Offset 与 Position 动画 Flet 隐式动画实战指南用 Python 为控件添加 Opacity、Rotation、Scale、Offset 与 Position 动画【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/fletFlet 官方在 2022 年 8 月发布的博客《Fun with animations》中正式公开了隐式动画Implicit Animations的完整文档并同步带来AnimatedSwitcher、Markdown、ShaderMask等一批新控件与新能力。本文以这篇博客为主线结合当前仓库中的官方示例与 Python SDK 源码系统讲解如何用纯 Python 为 Flet 控件添加透明度、旋转、缩放、位移与位置动画并串联动画结束回调、内容切换动画及同版本配套新特性帮助你直接在 Flet 应用中落地可运行的动画方案。一、隐式动画只需要设置目标值Flet 基于 Flutter 构建而 Flutter 官方提供了隐式implicit、显式explicit、补间tween、交错staggered、预置pre-canned动画以及 Rive / Lottie 动画场景等多种动画方案。Flet 从隐式动画切入你只需要为某个可动画属性设置一个目标值当目标值变化时控件会自动从旧值插值过渡到新值无需手动管理动画控制器。插值过程发生在给定的duration时长内默认情况下动画值随时间线性增长但你可以通过curve缓动曲线改变取值节奏。例如AnimationCurve.EASE_OUT_CUBIC会让动画在开始时快速推进、接近目标值时逐渐减速。在仓库的 Python SDK 中Animation与AnimationCurve定义于sdk/python/packages/flet/src/flet/controls/animation.py。Animation是一个值对象核心字段只有两个duration动画时长传整数时按毫秒解释也可以用Duration对象获得更精细的控制curve缓动曲线默认AnimationCurve.LINEAR。它同时提供了copy()方法可以基于现有配置覆写部分属性生成新实例便于在运行时复用动画配置。AnimationCurve则是一个覆盖完整 FlutterCurves曲线的枚举仓库中实现了 30 余种曲线常用示例包括曲线含义LINEAR匀速运动默认值EASE_IN/EASE_OUT/EASE_IN_OUT标准缓入、缓出、缓入缓出EASE_IN_CUBIC/EASE_OUT_CUBIC/EASE_IN_OUT_CUBIC三次贝塞尔缓动过渡更顺滑BOUNCE_IN/BOUNCE_OUT/BOUNCE_IN_OUT带弹跳效果适合活泼的交互反馈ELASTIC_IN/ELASTIC_OUT/ELASTIC_IN_OUT弹簧回弹效果FAST_OUT_SLOWINMaterial 动效曲线快速启动、平缓收尾EASE_IN_OUT_CUBIC_EMPHASIZEDMaterial 3 强调式缓动animate_*属性的三种取值方式LayoutControl及其子类提供了一组animate_{something}属性来开启隐式动画它们统一接受以下三种取值类型别名AnimationValue Union[bool, int, Animation]见animation.py末尾的类型定义Animation实例完整配置时长与曲线例如animate_rotationft.Animation(duration300, curveft.AnimationCurve.BOUNCE_OUT)整数启用动画并指定时长毫秒曲线使用LINEAR布尔值True启用动画时长为 1000 毫秒曲线使用LINEAR。二、五大隐式动画属性逐个实战以下示例全部来自仓库sdk/python/examples/controls/core/layout_control/目录均可直接运行。1. 透明度动画animate_opacity设置animate_opacity为True、整数或Animation实例后控件会隐式动画化Control.opacity属性取值范围 0.01.0import flet as ft def main(page: ft.Page): def animate_opacity(e: ft.Event[ft.Button]): container.opacity 0 if container.opacity 1 else 1 container.update() page.add( ft.SafeArea( contentft.Column( controls[ container : ft.Container( width150, height150, bgcolorft.Colors.BLUE, border_radius10, animate_opacity300, # 300ms 线性淡入淡出 ), ft.Button( contentAnimate opacity, on_clickanimate_opacity, ), ], ), ) ) if __name__ __main__: ft.run(main)2. 旋转动画animate_rotation本版本新增通过LayoutControl.rotate设置旋转角度与对齐方式配合animate_rotation即可平滑旋转。示例中每次点击让蓝色容器旋转 90 度并使用BOUNCE_OUT曲线获得带弹性的旋转效果from math import pi import flet as ft def main(page: ft.Page): page.vertical_alignment ft.MainAxisAlignment.CENTER page.horizontal_alignment ft.CrossAxisAlignment.CENTER page.spacing 30 def animate(e: ft.Event[ft.Button]): container.rotate.angle pi / 2 container.update() page.add( ft.SafeArea( contentft.Column( horizontal_alignmentft.CrossAxisAlignment.CENTER, controls[ container : ft.Container( width100, height70, bgcolorft.Colors.BLUE, border_radius5, rotateft.Rotate(angle0, alignmentft.Alignment.CENTER), animate_rotationft.Animation( duration300, curveft.AnimationCurve.BOUNCE_OUT, ), ), ft.Button(Animate!, on_clickanimate), ], ), ) ) if __name__ __main__: ft.run(main)3. 缩放动画animate_scale本版本新增配合LayoutControl.scale属性数值型1.0 为原始大小animate_scale让控件在点击时平滑放大到 2 倍再缩回import flet as ft def main(page: ft.Page): page.vertical_alignment ft.MainAxisAlignment.CENTER page.horizontal_alignment ft.CrossAxisAlignment.CENTER page.spacing 30 def animate(e: ft.Event[ft.Button]): container.scale 2 if container.scale 1 else 1 container.update() page.add( ft.SafeArea( contentft.Column( horizontal_alignmentft.CrossAxisAlignment.CENTER, controls[ container : ft.Container( width100, height100, bgcolorft.Colors.BLUE, border_radius5, scale1, animate_scaleft.Animation( duration600, curveft.AnimationCurve.BOUNCE_OUT, ), ), ft.Button(Animate!, on_clickanimate), ], ), ) ) if __name__ __main__: ft.run(main)4. 位移动画animate_offset本版本新增offset是Offset类的实例其x、y值按控件尺寸比例解释例如Offset(-0.25, 0)表示水平向左平移四分之一控件宽度。因此位移动画非常适合实现滑入、滑出等滑动效果import flet as ft def main(page: ft.Page): def animate(e: ft.Event[ft.Button]): container.offset ft.Offset(0, 0) container.update() page.add( ft.SafeArea( contentft.Column( controls[ container : ft.Container( width150, height150, bgcolorft.Colors.BLUE, border_radiusft.BorderRadius.all(10), offsetft.Offset(x-1.1, y0), # 初始完全滑出左侧 animate_offsetft.Animation( duration600, curveft.AnimationCurve.BOUNCE_OUT, ), ), ft.Button(Reveal!, on_clickanimate), ], ), ) ) if __name__ __main__: ft.run(main)5. 位置动画animate_positionanimate_position动画化的是left、right、bottom、top四个定位属性。需要注意定位仅在控件是Stack的子级或位于Page.overlay列表中时生效见Stack控件文档。下面的示例在一个Stack中放置三个彩色方块点击按钮后它们各自移动到新坐标且每个方块可以配置不同的动画时长import flet as ft def main(page: ft.Page): def animate_container(e: ft.Event[ft.Button]): c1.top 20 c1.left 200 c2.top 100 c2.left 40 c3.top 180 c3.left 100 stack.update() page.add( ft.SafeArea( contentft.Column( controls[ stack : ft.Stack( height400, controls[ c1 : ft.Container( width50, height50, bgcolorred, animate_position1000, ), c2 : ft.Container( width50, height50, bgcolorgreen, top60, left0, animate_position500, ), c3 : ft.Container( width50, height50, bgcolorblue, top120, left0, animate_position1000, ), ], ), ft.Button(Animate!, on_clickanimate_container), ], ), ) ) if __name__ __main__: ft.run(main)6.Container.animate容器全能动画除上述五个属性外Container还拥有独立的animate属性接受AnimationValue可以为尺寸、背景色、边框样式、渐变等容器属性统一开启隐式动画。官方 cookbook 提供了完整的尺寸与颜色同步动画示例详见website/docs/cookbook/animations.md中的 Animate 一节。三、AnimatedSwitcher新旧内容之间的过渡动画博客同时引入了新的AnimatedSwitcher控件用于在两个控件新内容与旧内容之间做动画过渡只要修改其content属性切换器就会自动为旧内容执行退出动画、为新内容执行进入动画。从源码sdk/python/packages/flet/src/flet/controls/core/animated_switcher.py可以看到其核心配置transition过渡策略枚举AnimatedSwitcherTransition可选FADE交叉淡入淡出默认、ROTATION旋转切换、SCALE缩放切换duration/reverse_duration新内容进入、旧内容退出的时长默认各 1 秒switch_in_curve/switch_out_curve进入与退出的缓动曲线默认LINEAR。下面是一个完整的可运行示例来自sdk/python/examples/controls/core/animated_switcher/scale_effect/main.py两个容器分别显示 Hello! 与 Bye!三个按钮可以随时切换缩放、淡入淡出、旋转三种过渡方式import flet as ft def main(page: ft.Page): c1 ft.Container( contentft.Text(Hello!, theme_styleft.TextThemeStyle.HEADLINE_MEDIUM), alignmentft.Alignment.CENTER, width200, height200, bgcolorft.Colors.GREEN, ) c2 ft.Container( contentft.Text(Bye!, size50), alignmentft.Alignment.CENTER, width200, height200, bgcolorft.Colors.YELLOW, ) switcher ft.AnimatedSwitcher( contentc1, transitionft.AnimatedSwitcherTransition.SCALE, duration500, reverse_duration100, switch_in_curveft.AnimationCurve.BOUNCE_OUT, switch_out_curveft.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( ft.SafeArea( contentft.Column( controls[ switcher, ft.Button(Scale, on_clickscale), ft.Button(Fade, on_clickfade), ft.Button(Rotate, on_clickrotate), ] ) ), ) if __name__ __main__: ft.run(main)四、动画结束回调串联多段动画LayoutControl还提供了on_animation_end事件处理器在动画完成时被调用可用于把多段动画串联成序列。事件对象data字段会携带结束动画的名称取值包括opacity、rotation、scale、offset、position、container详见cookbook/animations.md的 Animation end callback 一节 与Event类型文档。ft.Container( contentft.Text(Animate me!), animateft.Animation(1000, ft.AnimationCurve.BOUNCE_OUT), on_animation_endlambda e: print(Container animation end:, e.data), )五、同版本新增的配套能力除了动画本身该版本还一并发布了以下新控件与新能力使动画场景更完整。Markdown控件新的Markdown控件可在 Flet 应用中直接渲染 Markdown 文本支持CommonMark、GitHub Web、GitHub Flavored等多种扩展风格并支持代码语法高亮与自定义文本主题适合文档展示、聊天记录等场景。使用page.launch_url()打开链接Page.launch_url(url)方法可以在新浏览器窗口中打开 URLpage.launch_url(https://google.com)该方法与Markdown控件配合良好——可让 Markdown 文档内的链接直接通过它打开实现可点击的富文本内容。全局键盘事件on_keyboard_eventPage新增了on_keyboard_event事件处理器见Page控件文档可以在全局层面拦截所有按键输入适用于快捷键、游戏操控等需要监听全局键盘的场景。无障碍Accessibility支持该版本在文档中新增了无障碍Accessibility章节介绍利用 semantics 语义信息为屏幕阅读器提供可读内容让 Flet 应用对视力障碍用户更友好。ShaderMask控件ShaderMask使用 shader 生成的遮罩作用于控件内容典型效果是让图片边缘逐渐淡出。仓库示例中包含pink_radial_glow粉色径向光晕、fade_out_image_bottom图片底部淡出等可直接参考的用例适合制作精致的视觉装饰。结语通过隐式动画机制Flet 让为界面添加动效变成了一件几乎零成本的事给属性设置目标值、配置animate_*开关剩下的插值与重绘完全由框架完成。结合AnimatedSwitcher的内容过渡、on_animation_end的动画串联以及Markdown、ShaderMask等配套控件你可以在纯 Python 下构建出具有流畅交互动效的 Web、桌面与移动应用。动手运行本文给出的任一示例全部位于sdk/python/examples/controls/core/目录即可直观感受隐式动画的魅力。【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询