Flet FloatingActionButton(悬浮操作按钮)完全指南:从页面挂载到源码实现
【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet
FloatingActionButton(简称 FAB)是 Material Design 中用于承载页面"主操作"的悬浮圆形按钮,在 Flet 中既可作为全局按钮挂载到page.floating_action_button,也可作为普通控件嵌入任意布局。本文以 官方控件文档 为骨架,结合 Python 控件源码 与 Flutter 渲染实现,系统讲解其属性、位置、主题定制与事件机制,读完后你将能够独立实现"点击 FAB 触发主操作"的完整交互并掌握其底层工作原理。
认识 FloatingActionButton
从源码看,FloatingActionButton是一个典型的 Material 控件,定义于 floating_action_button.py:
@control("FloatingActionButton") class FloatingActionButton(LayoutControl, ActionControl):它同时继承了两个基类,因此天然具备两类能力:
- LayoutControl:参与页面布局,拥有尺寸(
width、height、aspect_ratio)、绝对定位(left、top、right、bottom)、2D 变换(rotate、scale、offset、flip)以及animate_*系列隐式动画属性,定义见 layout_control.py。这意味着 FAB 不仅可以悬浮,还能被旋转、缩放、位移甚至做入场动画。 - ActionControl:支持
action属性,可在客户端(浏览器/移动端)于用户点击手势内部直接执行"打开文件选择器、写入剪贴板、分享、打开新标签页"等操作,避免一次 Python 往返耗时导致浏览器权限失效,详见 action_control.py。
此外,FAB 的官方定位是"悬浮于内容之上、突出页面主操作",因此最典型的用法是挂载到页面根视图:
page.floating_action_button = ft.FloatingActionButton(icon=ft.Icons.ADD)page.floating_action_button与page.floating_action_button_location两个属性定义在 base_page.py 中;View与Pagelet控件同样支持这两个属性(见 view.py 与 pagelet.py),因此你也可以在View或Pagelet作用域内挂载各自的 FAB。
完整示例:点击 FAB 添加列表项
官方文档引用的示例位于 sdk/python/examples/controls/material/floating_action_button/handling_clicks/main.py,完整代码如下,可直接运行:
import flet as ft def main(page: ft.Page): page.title = "Floating Action Button" page.theme_mode = ft.ThemeMode.LIGHT page.horizontal_alignment = ft.CrossAxisAlignment.CENTER page.padding = 0 page.scroll = ft.ScrollMode.HIDDEN count = 1 def handle_fab_click(e: ft.Event[ft.FloatingActionButton]): nonlocal count page.add( ft.ListTile( title=ft.Text(f"Tile {count}"), bgcolor=ft.Colors.TEAL_300, leading=ft.Icon( ft.Icons.CIRCLE_OUTLINED, color=ft.Colors.DEEP_ORANGE_300, ), on_click=lambda x: print(x.control.title.value + " was clicked!"), ) ) page.show_dialog(ft.SnackBar(ft.Text("Tile was added successfully!"))) count += 1 page.floating_action_button = ft.FloatingActionButton( key="handling_clicks_fab", icon=ft.Icons.ADD, on_click=handle_fab_click, bgcolor=ft.Colors.LIME_300, ) page.add( ft.SafeArea( content=ft.Column( controls=[ ft.Container( bgcolor=ft.Colors.BLUE, padding=ft.Padding.all(20), content=ft.Row( alignment=ft.MainAxisAlignment.CENTER, controls=[ ft.Text( value="Floating Action Button Example", style=ft.TextStyle( size=20, weight=ft.FontWeight.W_500, ), ) ], ), ), ft.Text("Press the FAB to add a tile!"), ], ), ) ) if __name__ == "__main__": ft.run(main)该示例覆盖了 FAB 使用中的三个关键点:
- 挂载方式:通过
page.floating_action_button = ft.FloatingActionButton(...)将 FAB 挂到页面根视图,自动悬浮于内容右下角; - 事件绑定:
on_click回调接收类型为ft.Event[ft.FloatingActionButton]的事件对象,可在回调中修改页面内容; - 交互反馈:点击后通过
page.show_dialog(ft.SnackBar(...))弹出提示条,属于 Material 推荐的 FAB 反馈模式。
核心属性详解
FAB 的全部属性都定义在 floating_action_button.py,下面按功能分组说明。
内容与外观
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
icon | IconDataOrControl | None | 按钮内显示的图标(如ft.Icons.ADD),可以是图标数据或任意控件 |
content | StrOrControl | None | 按钮内容,字符串或可见控件;同时提供icon与content时 FAB 自动变为**扩展型(extended)**样式 |
bgcolor | ColorValue | None | 按钮背景色 |
foreground_color | ColorValue | None | 图标与文字的默认前景色 |
shape | OutlinedBorder | None | FAB 边框形状(如圆角/圆形边框) |
clip_behavior | ClipBehavior | ClipBehavior.NONE | 内容超出按钮边界时的裁剪方式 |
验证规则:源码末尾的
__validation_rules__(floating_action_button.py)强制要求icon或content(字符串或可见控件)至少提供其一,否则抛出ValueError。Flutter 端渲染时同样会检查:若两者皆空则渲染ErrorControl提示"Provide at minimum icon or content"(见 floating_action_button.dart)。
尺寸:mini 与扩展模式
| 属性 | 默认值 | 说明 |
|---|---|---|
mini | False | 是否为迷你尺寸。标准 FAB 高宽为56.0逻辑像素;mini FAB 高宽为40.0,布局占位为48.0逻辑像素 |
Flutter 端根据icon与content的提供情况选择构造器(见 floating_action_button.dart):
- 仅提供
icon或仅提供content→ 使用FloatingActionButton(...)(圆形图标按钮,配合mini控制大小); - 同时提供
icon与content→ 自动使用FloatingActionButton.extended(...),渲染为"图标 + 文本"的胶囊形扩展 FAB,此时mini不再生效,文本样式与间距由主题层控制。
高程(Elevation)体系
FAB 悬浮于内容之上,其阴影深浅通过高程表达。源码定义了五个高程属性,且均带V.ge(0)校验(负值会抛ValueError):
| 属性 | 默认值 | 触发场景 |
|---|---|---|
elevation | 6 | 常规状态 |
disabled_elevation | 同elevation | 控件被禁用 |
focus_elevation | 8 | 获得输入焦点 |
hover_elevation | 8 | 悬停(桌面端鼠标) |
highlight_elevation | 12 | 按下高亮 |
交互反馈
| 属性 | 默认值 | 说明 |
|---|---|---|
hover_color | None | 悬停时的填充色 |
focus_color | None | 获得焦点时的填充色 |
splash_color | None | 点击时墨迹水波(ink splash)的颜色 |
enable_feedback | None | 手势是否附带声学/触觉反馈;Android 上为True时点击有提示音、长按有短暂振动 |
autofocus | False | 是否作为页面初始焦点;多个控件同时设置时,以第一个加入页面的为准 |
mouse_cursor | None | 鼠标悬停时的光标样式 |
url | None | 点击时打开的 URL;若同时设置了on_click,URL 打开动作先发生,随后触发on_click |
on_click | None | 点击事件回调,类型为ControlEventHandler["FloatingActionButton"] |
控制 FAB 的位置
FAB 在页面根视图上的位置由page.floating_action_button_location控制,可选值定义在 types.py 的FloatingActionButtonLocation枚举中,也可直接传Offset实现任意偏移:
| 枚举值 | 含义 |
|---|---|
CENTER_DOCKED | 居中并"停靠"在底部导航控件上方(按钮中心与导航顶边对齐) |
CENTER_FLOAT | 居中悬浮于屏幕底部 |
CENTER_TOP | 居中悬浮于 AppBar 与页面主体的过渡处 |
END_CONTAINED | 靠右,悬浮于底部导航控件上(与导航中心对齐) |
END_DOCKED | 靠右,"停靠"在底部导航控件上方(中心与导航顶边对齐) |
END_FLOAT | 靠右悬浮于屏幕底部,Material 应用中的默认位置 |
END_TOP | 靠右悬浮于 AppBar 与页面主体的过渡处 |
MINI_CENTER_*/MINI_END_* | 上述位置的迷你按钮变体,专为mini=True设计 |
源码注释特别指出:CENTER_DOCKED、END_DOCKED、END_CONTAINED适用于带底部导航控件的应用(如NavigationBar、Material 3BottomAppBar),无底部导航时通常无意义;*_TOP系列则依赖顶部AppBar存在。同时文档也提醒:使用 mini 按钮时应配合MINI_*系列位置以获得正确布局。
主题级定制:FloatingActionButtonTheme
若希望对页面内所有 FAB 统一风格,可在page.theme中通过floating_action_button_theme定制(见 theme.py)。FloatingActionButtonTheme类的完整字段定义于 theme.py,与控件属性一一对应:
- 颜色:
bgcolor、hover_color、focus_color、foreground_color、splash_color; - 高程:
elevation、focus_elevation、hover_elevation、highlight_elevation、disabled_elevation; - 形状与反馈:
shape、enable_feedback; - 扩展 FAB 专属:
extended_padding(图标与文本并存时的内边距)、text_style(合并进默认文本样式)、icon_label_spacing(图标与文本间距)、extended_size_constraints/size_constraints(尺寸约束)。
示例:给应用内所有 FAB 统一绿色背景与圆角形状:
import flet as ft page.theme = ft.Theme( floating_action_button_theme=ft.FloatingActionButtonTheme( bgcolor=ft.Colors.GREEN, shape=ft.RoundedRectangleBorder(radius=10), elevation=4, ) )控件级属性(如bgcolor)优先于主题级值,形成"全局主题兜底、局部属性覆盖"的层级关系。
源码级原理:点击事件如何到达 Python
从 Flutter 端 floating_action_button.dart 可以看到点击处理的关键链路:
Function()? onPressed = control.disabled ? null : () { runControlActions(context, control); control.triggerEvent("click"); };onPressed被置为null即按钮禁用态;点击时按顺序执行两件事:
runControlActions(context, control):先执行控件声明的客户端action(如复制到剪贴板、打开文件选择器),这些操作在浏览器/移动端"用户手势有效窗口"内立即完成;control.triggerEvent("click"):再将click事件通过 Flet 传输层发回 Python,触发on_click回调——这也是官方文档中"url打开动作先发生,on_click随后触发"的底层原因。
另外,FloatingActionButton的heroTag被设置为control.id(floating_action_button.dart),这意味着页面导航切换时,Flutter 的 Hero 动画会让 FAB 平滑过渡到下一页面对应的按钮上。
小结与更多资源
- 基本用法:
page.floating_action_button = ft.FloatingActionButton(icon=..., on_click=...)即可获得 Material 规范的悬浮主操作按钮;完整可运行示例见 handling_clicks/main.py。 - 内容形态:只有
icon/只有content为圆形按钮(mini可调小),icon与content并存自动变为扩展型 FAB。 - 位置与主题:通过
page.floating_action_button_location(FloatingActionButtonLocation枚举)控制摆放位置;通过page.theme.floating_action_button_theme做全局统一风格。 - 底层机制:客户端 action 先于
click事件执行,heroTag由控件 id 决定,按钮禁用态通过onPressed = null实现。
如需查阅控件全部成员的完整文档,可直接阅读官方页面 website/docs/controls/floatingactionbutton.md;源码级定义请参考 floating_action_button.py、FloatingActionButtonLocation 枚举 与 FloatingActionButtonTheme。
【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考