主题
InputBorder 现在是类层级结构,而非枚举
概述
Flet 1.0.0 用一套类层级结构替换了 InputBorder 枚举,它与 Flutter 的 InputBorder 相对应:
- [
OutlineInputBorder][flet.OutlineInputBorder] —— 围绕各边的圆角矩形(side、border_radius、gap_padding) - [
UnderlineInputBorder][flet.UnderlineInputBorder] —— 沿底边的一条线(side、border_radius) - [
NoInputBorder][flet.NoInputBorder] —— 不绘制任何内容
旧 API 所能表达的一切——以及更多——现在都落在 border 属性上,它接受单个 InputBorder,或是一个将 [ControlState][flet.ControlState] 映射到 InputBorder 的字典。
当新旧写法结合时,新 API 获胜:一个指定了 side 或按状态条目的 border 会完全忽略那些被废弃的属性,而一个裸的 border=ft.InputBorder.UNDERLINE 仍会拾取旧的 border_color。
背景
旧的枚举加五个松散属性无法表达 Flutter 真正的 API:gap_padding 没有被暴露,UnderlineInputBorder 的圆角被忽略,而且错误/禁用边框根本无法设置样式。Flutter 每新增一个边框属性,就需要在顶层控件上再增加一项属性。类层级结构改为随 Flutter 一起扩展:新的边框类型(例如 Flutter 3.44 加入的 ShapedInputBorder)成为新类,而不是每个表单字段上都多几个属性。
迁移指南
边框样式
迁移前代码:
python
ft.TextField(border=ft.InputBorder.OUTLINE)
ft.TextField(border=ft.InputBorder.UNDERLINE)
ft.TextField(border=ft.InputBorder.NONE)迁移后代码:
python
ft.TextField(border=ft.OutlineInputBorder()) # 默认值;可省略
ft.TextField(border=ft.UnderlineInputBorder())
ft.TextField(border=ft.NoInputBorder())圆角、颜色与宽度
迁移前代码:
python
ft.TextField(
border_radius=30,
border_color=ft.Colors.GREEN_800,
border_width=2,
)迁移后代码:
python
ft.TextField(
border=ft.OutlineInputBorder(
border_radius=30,
side=ft.BorderSide(width=2, color=ft.Colors.GREEN_800),
),
)要完全移除边框(之前用 border_width=0 或 border_color=ft.Colors.TRANSPARENT),使用 border=ft.NoInputBorder(),或者 side=ft.BorderSide.none() 来保留轮廓形状以配合填充。
与旧的 border_color 不同,单个边框上显式的 side 只作用于启用状态——聚焦边框仍保持主题色(主色,2px)。若要像旧代码那样也给聚焦边框上色,使用下面按状态的写法。
聚焦(以及其他按状态)边框
迁移前代码:
python
ft.TextField(
border_radius=30,
border_color=ft.Colors.GREEN_800,
focused_border_color=ft.Colors.GREEN_ACCENT_400,
focused_border_width=5,
)迁移后代码:
python
ft.TextField(
border={
ft.ControlState.DEFAULT: ft.OutlineInputBorder(
border_radius=30,
side=ft.BorderSide(color=ft.Colors.GREEN_800),
),
ft.ControlState.FOCUSED: ft.OutlineInputBorder(
border_radius=30,
side=ft.BorderSide(width=5, color=ft.Colors.GREEN_ACCENT_400),
),
},
)支持的 State 键为 DEFAULT、FOCUSED、ERROR 和 DISABLED——错误和禁用边框在以前是无法设置样式的。一个没有显式 side 的状态条目会回退到 DEFAULT 条目的 side,这与旧的 focused_border_color or border_color 的颜色行为一致。
ERROR 条目同时覆盖两种错误状态:字段在失焦时显示错误、以及在聚焦时显示错误。当它没有显式 side 时,聚焦变体会以更粗的 Material 聚焦权重绘制。
注意,显式的 side 会以它指定的精确宽度渲染——ft.BorderSide 默认宽度为 1。旧的隐式聚焦宽度 2(当 focused_border_width 和 border_width 都未设置时应用)不复存在:要在 FOCUSED 条目中保留先前的聚焦强调,请传入 side=ft.BorderSide(width=2, ...)。
DropdownM2 菜单圆角
DropdownM2.border_radius 以前会同时圆化输入框和打开的菜单。现在它们是分开的:border 塑造输入框,新的 menu_border_radius 塑造菜单。两者都设置才能保持旧外观。
迁移前代码:
python
ft.DropdownM2(border_radius=20)迁移后代码:
python
ft.DropdownM2(
border=ft.OutlineInputBorder(border_radius=20),
menu_border_radius=20,
)读取与比较边框
ft.InputBorder 不再是枚举,因此那些检查而非设置边框的代码需要更新。没有可供比较或迭代的枚举成员。
迁移前代码:
python
if field.border == ft.InputBorder.NONE:
...
for style in ft.InputBorder:
...迁移后代码:
python
if field.border == ft.NoInputBorder():
...
for style in (
ft.OutlineInputBorder(),
ft.UnderlineInputBorder(),
ft.NoInputBorder(),
):
...边框按值比较,因此 ft.OutlineInputBorder(border_radius=4) 等于 ft.OutlineInputBorder()——4 是默认值。要只测试边框的种类,使用 isinstance(field.border, ft.OutlineInputBorder)。注意 field.border 也可能保存一个 ControlState 字典,而非单个边框。
需要注意的行为变化
- 默认采用主题驱动的边框颜色(Material 控件:
TextField、Dropdown、DropdownM2)。以前启用状态的边框总是画成黑色,除非设置了border_color——在深色模式下也一样。现在没有显式side的边框会让 Material 主题按状态解析颜色和宽度:聚焦用主色,错误用错误色,启用色来自主题轮廓(或对于filled字段,来自其激活指示色)。这是 Flutter 的默认行为,并且在深色模式和自定义主题下都能正确工作。 - 单个边框上的显式
side只作用于启用状态。 以前border_color也会给聚焦边框上色。现在聚焦、错误和禁用状态都保持主题解析(聚焦:主色,2px),除非你使用ControlState字典形式——参见上面的按状态示例来恢复旧的聚焦外观。 - 下划线边框现在会遵循圆角。 旧的
border_radius属性只应用于轮廓边框,当border为InputBorder.UNDERLINE时被静默忽略。UnderlineInputBorder.border_radius现在会原样传给 Flutter,由它来圆化装饰容器的圆角——在字段为filled时可见,因为填充会被裁剪到该圆角。边框本身仍沿底边画成一条线。它的上角默认圆角为4。 CupertinoTextField绘制的是盒子装饰而非 Material 输入装饰,因此它翻译边框的方式不同。保持border未设置会保留原生 iOS 细线,与之前完全一致。两个显式值会改变外观:ft.OutlineInputBorder()在没有side时现在也保留那条原生细线,而InputBorder.OUTLINE过去会画一个实心黑色 1px 盒子(传入side来自己绘制);并且ft.NoInputBorder()现在会真正移除边框,而InputBorder.NONE过去是被静默忽略的。带显式side的轮廓会在所有边绘制,下划线只绘制底边,现在还会为填充遵循非默认border_radius。等于轮廓默认值(4)的border_radius与未设置无法区分,并保留原生半径5。在ControlState字典形式中,会应用DEFAULT、FOCUSED和DISABLED条目;ERROR被忽略,因为该控件不渲染错误状态。
时间线
- 废弃于:
1.0.0 - 移除于:
1.3.0
参考
- API 文档:[
InputBorder][flet.InputBorder]、 [OutlineInputBorder][flet.OutlineInputBorder]、 [UnderlineInputBorder][flet.UnderlineInputBorder]、 [NoInputBorder][flet.NoInputBorder]、 [ControlState][flet.ControlState] - Flutter
InputBorderAPI - 问题与 PR:#6773
- 发布说明:Flet 1.0.0