Flutter按钮迁移 FlatButton RaisedButton OutlineButton
添加了一组新的基本材质按钮小部件和主题 到颤动。原始类已被弃用,将 最终被移除。总体目标是使按钮更多 灵活,更易于通过构造函数参数或 主题。
和 小部件已被 分别替换为 、 和。每个新按钮类都有自己的主题:、 和 。原来的类不再是 使用。按钮的外观由对象指定,而不是一大组小部件参数和 性能。这与外观大致相当 的文本是用对象定义的。新的按钮主题 还配置了一个对象。A 是 本身只是视觉属性的集合。其中许多 属性是用 定义的,这意味着 它们的值可能取决于按钮的状态。FlatButton``RaisedButton``OutlineButton``TextButton``ElevatedButton``OutlinedButton``TextButtonTheme``ElevatedButtonTheme``OutlinedButtonTheme``ButtonTheme``ButtonStyle``TextStyle``ButtonStyle``ButtonStyle``MaterialStateProperty
上下文
而不是尝试发展现有的按钮类及其主题 就地,我们引入了新的替换按钮小部件和 主题。除了将我们从向后兼容性中解放出来之外 就地发展现有类需要的迷宫, 新名称将 Flutter 与材料设计规范同步, 它使用按钮组件的新名称。
旧小部件 | 旧主题 | 新建小部件 | 新主题 |
---|---|---|---|
FlatButton |
ButtonTheme |
TextButton |
TextButtonTheme |
RaisedButton |
ButtonTheme |
ElevatedButton |
ElevatedButtonTheme |
OutlineButton |
ButtonTheme |
OutlinedButton |
OutlinedButtonTheme |
新主题遵循 Flutter 采用的“标准化”模式 大约一年前的新材质小部件。主题属性和小部件 默认情况下,构造函数参数为 null。非空主题属性 和小部件参数指定组件默认值的覆盖 价值。实现和记录默认值是唯一的 按钮组件小部件的责任。默认值 本身主要基于整体主题的配色方案和 文本主题。
从视觉上看,新按钮看起来有点不同,因为它们匹配 当前的材料设计规范,因为它们的颜色是 根据整体主题的配色方案进行配置。有 填充、圆角半径和 悬停/聚焦/按下反馈。
许多应用程序将能够只替换新的类名 对于旧的。具有最佳配置映像测试或具有其按钮的应用 外观已使用构造函数参数或 原件可能需要查阅迁移指南和 介绍性材料如下。ButtonTheme
API 更改:按钮样式而不是单个样式属性
除了简单的用例,新按钮类的 API 是 与旧类不兼容。新的视觉属性 按钮和主题配置了单个对象, 类似于如何用对象配置 OR 小部件。大多数属性都使用 定义,因此单个属性可以表示 根据按钮的按下/聚焦/悬停/等的不同值 州。ButtonStyle``TextField``Text``TextStyle``ButtonStyle``MaterialStateProperty
按钮不定义按钮的可视属性, 它定义了按钮默认视觉属性的替代, 其中,默认属性由按钮小组件计算 本身。例如,覆盖 的默认前景 (文本/图标)颜色 对于所有状态,可以这样写:ButtonStyle``TextButton
content_copy
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
),
onPressed: () { },
child: Text('TextButton'),
)
这种覆盖很常见;但是,在许多情况下,还有什么 需要覆盖文本按钮使用的叠加颜色 以指示其悬停/聚焦/按下状态。这可以通过以下方式完成 将属性添加到 .overlayColor``ButtonStyle
content_copy
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
overlayColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.hovered))
return Colors.blue.withOpacity(0.04);
if (states.contains(MaterialState.focused) ||
states.contains(MaterialState.pressed))
return Colors.blue.withOpacity(0.12);
return null; // Defer to the widget's default.
},
),
),
onPressed: () { },
child: Text('TextButton')
)
颜色只需要返回一个值 应覆盖其默认值的颜色。如果返回空值,则 将改用小部件的默认值。例如,仅覆盖 文本按钮的焦点叠加颜色:MaterialStateProperty
content_copy
TextButton(
style: ButtonStyle(
overlayColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.focused))
return Colors.red;
return null; // Defer to the widget's default.
}
),
),
onPressed: () { },
child: Text('TextButton'),
)
按钮样式实用工具方法styleFrom()
“材质设计”规范定义了按钮的前景色和叠加颜色 配色方案原色的术语。原色为 以不同的不透明度呈现,具体取决于按钮的状态。自 简化创建包含所有属性的按钮样式 取决于配色方案颜色,每个按钮类都包含一个 static styleFrom() 方法,它从一个简单的构造 一组值,包括它所依赖的颜色。ButtonStyle``ColorScheme
本示例创建一个覆盖其前景色的按钮,如 以及其覆盖颜色,使用指定的原色和 材质设计规范中的不透明度。
content_copy
TextButton(
style: TextButton.styleFrom(
primary: Colors.blue,
),
onPressed: () { },
child: Text('TextButton'),
)
文档指示前景色在以下情况下 按钮的禁用基于配色方案的颜色。要覆盖它,请使用 styleFrom():TextButton``onSurface
content_copy
TextButton(
style: TextButton.styleFrom(
primary: Colors.blue,
onSurface: Colors.red,
),
onPressed: null,
child: Text('TextButton'),
)
如果您尝试创建材料设计,则使用该方法是创建 变化。最灵活的方法是直接定义一个,为以下状态定义值 要覆盖的外观。styleFrom()``ButtonStyle``ButtonStyle``MaterialStateProperty
按钮样式默认值
像新按钮类这样的小部件计算其默认值 基于整体主题和以及 按钮的当前状态。在少数情况下,他们还考虑 整体主题的配色方案是浅色或深色。每个按钮都有一个 根据需要计算其默认样式的受保护方法。虽然 应用程序不会直接调用此方法,其 API 文档解释了所有内容 的默认值是。当按钮或按钮主题指定 时,只有按钮样式的非 null 属性将覆盖 计算的默认值。按钮的参数将覆盖非空值 由相应的按钮主题指定的属性。例如,如果 的样式的属性为非空,则 重写 样式的相同属性。colorScheme``textTheme``ButtonStyle``style``foregroundColor``TextButton``TextButonTheme
如前所述,每个按钮类都包含一个静态方法 调用,它从一组简单的 值,包括它所依赖的颜色。在许多常见的 案例,用于创建一次性的 覆盖默认值,是最简单的。当 自定义样式的目标是覆盖其中一个配色方案 颜色,例如默认样式取决于的颜色 上。对于其他情况,您可以创建一个对象 径直。这样做可以控制视觉对象的值 所有按钮可能状态的属性,如颜色 - 如按下、悬停、禁用和聚焦。styleFrom``ColorScheme``styleFrom``ButtonStyle``primary``onPrimary``ButtonStyle
迁移指南
使用以下信息将按钮迁移到 新的 API。
还原原始按钮视觉对象
在许多情况下,可以从旧的按钮类切换 到新的。这是假设大小/形状的微小变化 颜色可能更大的变化,这不是一个问题。
为了在这些情况下保留原始按钮的外观,可以 定义与原始按钮样式尽可能匹配的按钮样式 喜欢。例如,以下样式使外观 像默认值:TextButton``FlatButton
content_copy
final ButtonStyle flatButtonStyle = TextButton.styleFrom(
primary: Colors.black87,
minimumSize: Size(88, 36),
padding: EdgeInsets.symmetric(horizontal: 16.0),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(2.0)),
),
);
TextButton(
style: flatButtonStyle,
onPressed: () { },
child: Text('Looks like a FlatButton'),
)
同样,要使看起来像默认值:ElevatedButton``RaisedButton
content_copy
final ButtonStyle raisedButtonStyle = ElevatedButton.styleFrom(
onPrimary: Colors.black87,
primary: Colors.grey[300],
minimumSize: Size(88, 36),
padding: EdgeInsets.symmetric(horizontal: 16),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(2)),
),
);
ElevatedButton(
style: raisedButtonStyle,
onPressed: () { },
child: Text('Looks like a RaisedButton'),
)
的风格多一点 复杂,因为轮廓的颜色更改为原色 按下按钮时。轮廓的外观由 定义,您将使用 a 来定义按下的 轮廓颜色:OutlineButton``OutlinedButton``BorderSide``MaterialStateProperty
content_copy
final ButtonStyle outlineButtonStyle = OutlinedButton.styleFrom(
primary: Colors.black87,
minimumSize: Size(88, 36),
padding: EdgeInsets.symmetric(horizontal: 16),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(2)),
),
).copyWith(
side: MaterialStateProperty.resolveWith<BorderSide>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed))
return BorderSide(
color: Theme.of(context).colorScheme.primary,
width: 1,
);
return null; // Defer to the widget's default.
},
),
);
OutlinedButton(
style: outlineButtonStyle,
onPressed: () { },
child: Text('Looks like an OutlineButton'),
)
还原整个 应用程序中,您可以在 应用程序的主题:
content_copy
MaterialApp(
theme: ThemeData.from(colorScheme: ColorScheme.light()).copyWith(
textButtonTheme: TextButtonThemeData(style: flatButtonStyle),
elevatedButtonTheme: ElevatedButtonThemeData(style: raisedButtonStyle),
outlinedButtonTheme: OutlinedButtonThemeData(style: outlineButtonStyle),
),
)
还原部分按钮的默认外观 应用程序,您可以使用 、 或 包装小部件子树。例如:TextButtonTheme``ElevatedButtonTheme``OutlinedButtonTheme
content_copy
TextButtonTheme(
data: TextButtonThemeData(style: flatButtonStyle),
child: myWidgetSubtree,
)
迁移具有自定义颜色的按钮
以下各节介绍以下 、 和颜色参数的使用:FlatButton``RaisedButton``OutlineButton
content_copy
textColor
disabledTextColor
color
disabledColor
focusColor
hoverColor
highlightColor*
splashColor
新的按钮类不支持单独的突出显示颜色 因为它不再是材料设计的一部分。
迁移具有自定义前景色和背景色的按钮
原始按钮类的两个常见自定义项是自定义项 的前景色或自定义前景色和背景 的颜色。使用新的产生相同的结果 按钮类很简单:FlatButton``RaisedButton
content_copy
FlatButton(
textColor: Colors.red, // foreground
onPressed: () { },
child: Text('FlatButton with custom foreground/background'),
)
TextButton(
style: TextButton.styleFrom(
primary: Colors.red, // foreground
),
onPressed: () { },
child: Text('TextButton with custom foreground'),
)
在这种情况下,前景色(文本/图标)颜色以及 其悬停/聚焦/按下的叠加颜色将基于 .默认情况下,的背景填充颜色为 透明。TextButton``Colors.red``TextButton
使用自定义前景色和背景色迁移 :RaisedButton
content_copy
RaisedButton(
color: Colors.red, // background
textColor: Colors.white, // foreground
onPressed: () { },
child: Text('RaisedButton with custom foreground/background'),
)
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red, // background
onPrimary: Colors.white, // foreground
),
onPressed: () { },
child: Text('ElevatedButton with custom foreground/background'),
)
在这种情况下,按钮对配色方案原色的使用是 相对于:主要按钮的背景反转 填充颜色,是前景色(文本/图标)颜色。TextButton``onPrimary
使用自定义叠加颜色迁移按钮
覆盖按钮的默认焦点、悬停、突出显示或启动 颜色不太常见。、 和 类具有这些状态相关的单独参数 颜色。新的、 和 类 请改用单个参数。新的 按钮允许为所有 颜色,仅支持原始按钮指定现在的内容 称为“覆盖颜色”。FlatButton``RaisedButton``OutlineButton``TextButton``ElevatedButton``OutlinedButton``MaterialStateProperty
content_copy
FlatButton(
focusColor: Colors.red,
hoverColor: Colors.green,
splashColor: Colors.blue,
onPressed: () { },
child: Text('FlatButton with custom overlay colors'),
)
TextButton(
style: ButtonStyle(
overlayColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.focused))
return Colors.red;
if (states.contains(MaterialState.hovered))
return Colors.green;
if (states.contains(MaterialState.pressed))
return Colors.blue;
return null; // Defer to the widget's default.
}),
),
onPressed: () { },
child: Text('TextButton with custom overlay colors'),
)
新版本更灵活,但不太紧凑。在 原始版本,不同状态的优先级是 隐式(和未记录)和固定的,在新版本中,它是 明确。对于经常指定这些颜色的应用, 最简单的迁移路径是定义一个或多个与上述示例匹配的迁移路径 - 并且仅使用 style 参数 - 或 定义封装三种颜色的无状态包装器小部件 参数。ButtonStyles
迁移具有自定义禁用颜色的按钮
这是一个相对罕见的自定义。、 和 类具有定义背景和前景的参数 当按钮的回调为 null 时的颜色。FlatButton``RaisedButton``OutlineButton``disabledTextColor``disabledColor``onPressed
默认情况下,所有按钮都使用配色方案的颜色, 禁用前景色的不透明度为 0.38。仅具有非透明背景颜色及其默认值 值是不透明度为 0.12 的颜色。所以在很多情况下一个 可以使用该方法覆盖禁用的颜色:onSurface``ElevatedButton``onSurface``styleFrom
content_copy
RaisedButton(
disabledColor: Colors.red.withOpacity(0.12),
disabledTextColor: Colors.red.withOpacity(0.38),
onPressed: null,
child: Text('RaisedButton with custom disabled colors'),
),
ElevatedButton(
style: ElevatedButton.styleFrom(onSurface: Colors.red),
onPressed: null,
child: Text('ElevatedButton with custom disabled colors'),
)
为了完全控制禁用的颜色,必须明确定义 的样式,如下所示:ElevatedButton``MaterialStateProperties
content_copy
RaisedButton(
disabledColor: Colors.red,
disabledTextColor: Colors.blue,
onPressed: null,
child: Text('RaisedButton with custom disabled colors'),
)
ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled))
return Colors.red;
return null; // Defer to the widget's default.
}),
foregroundColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled))
return Colors.blue;
return null; // Defer to the widget's default.
}),
),
onPressed: null,
child: Text('ElevatedButton with custom disabled colors'),
)
与前一种情况一样,有明显的方法可以使新的 在经常出现此迁移的应用程序中版本更紧凑。
使用自定义提升迁移按钮
这也是一种相对罕见的自定义。通常,只有 s(最初称为 ) 包括高程变化。对于成比例的高程 到基线高程(根据材料设计规范), 可以非常简单地覆盖所有这些。ElevatedButton``RaisedButtons
默认情况下,禁用按钮的提升为 0,其余 状态是相对于基线 2 定义的:
content_copy
disabled: 0
hovered or focused: baseline + 2
pressed: baseline + 6
因此,要迁移所有高程都已针对的 定义:RaisedButton
content_copy
RaisedButton(
elevation: 2,
focusElevation: 4,
hoverElevation: 4,
highlightElevation: 8,
disabledElevation: 0,
onPressed: () { },
child: Text('RaisedButton with custom elevations'),
)
ElevatedButton(
style: ElevatedButton.styleFrom(elevation: 2),
onPressed: () { },
child: Text('ElevatedButton with custom elevations'),
)
任意覆盖一个高程,例如按下 海拔:
content_copy
RaisedButton(
highlightElevation: 16,
onPressed: () { },
child: Text('RaisedButton with a custom elevation'),
)
ElevatedButton(
style: ButtonStyle(
elevation: MaterialStateProperty.resolveWith<double?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed))
return 16;
return null;
}),
),
onPressed: () { },
child: Text('ElevatedButton with a custom elevation'),
)
迁移具有自定义形状和边框的按钮
原始的、 和类全部 提供一个形状参数,用于定义按钮的形状和 其轮廓的外观。相应的新类及其 主题支持指定按钮的形状及其边框 分别,使用 和 参数。FlatButton``RaisedButton``OutlineButton``OutlinedBorder shape``BorderSide side
在此示例中,原始版本指定相同的 边框在其突出显示(按下)状态下的颜色与其他颜色一样 国家。OutlineButton
content_copy
OutlineButton(
shape: StadiumBorder(),
highlightedBorderColor: Colors.red,
borderSide: BorderSide(
width: 2,
color: Colors.red
),
onPressed: () { },
child: Text('OutlineButton with custom shape and border'),
)
OutlinedButton(
style: OutlinedButton.styleFrom(
shape: StadiumBorder(),
side: BorderSide(
width: 2,
color: Colors.red
),
),
onPressed: () { },
child: Text('OutlinedButton with custom shape and border'),
)
大多数新小部件的样式参数,包括 它的形状和边框可以用值指定,也就是说,它们可以根据 在按钮的状态上。在以下情况下指定不同的边框颜色 按钮,执行以下操作:OutlinedButton``MaterialStateProperty
content_copy
OutlineButton(
shape: StadiumBorder(),
highlightedBorderColor: Colors.blue,
borderSide: BorderSide(
width: 2,
color: Colors.red
),
onPressed: () { },
child: Text('OutlineButton with custom shape and border'),
)
OutlinedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<OutlinedBorder>(StadiumBorder()),
side: MaterialStateProperty.resolveWith<BorderSide>(
(Set<MaterialState> states) {
final Color color = states.contains(MaterialState.pressed)
? Colors.blue
: Colors.red;
return BorderSide(color: color, width: 2);
}
),
),
onPressed: () { },
child: Text('OutlinedButton with custom shape and border'),
)
时间轴
登陆版本:1.20.0-0.0.pre 稳定版本:2.0
引用
接口文档:
ButtonStyle
ButtonStyleButton
ElevatedButton
ElevatedButtonTheme
ElevatedButtonThemeData
OutlinedButton
OutlinedButtonTheme
OutlinedButtonThemeData
TextButton
TextButtonTheme
TextButtonThemeData
相关公关:
原文地址:(https://docs.flutter.dev/release/breaking-changes/buttons#context
发表评论