我使用以下代码更改SnackBarAction
的fontSize
:
最少的可重现代码:
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: Theme(
data: ThemeData(
textTheme: TextTheme(button: TextStyle(fontSize: 30)), // Doesn't work
primaryColor: Colors.orange, // Works
),
child: Builder(builder: (builderContext) {
return FloatingActionButton(
onPressed: () {
final snackBar = SnackBar(
content: Text('SnackBar'),
action: SnackBarAction(
label: 'Dismiss',
onPressed: () {},
),
);
ScaffoldMessenger.of(builderContext).showSnackBar(snackBar);
},
child: Icon(
Icons.slideshow,
color: Theme.of(builderContext).primaryColor,
),
);
}),
),
);
}
fontSize
属性似乎没有效果,但是如果我MaterialApp
小部件中使用相同的ThemeData
(如下所示),它可以工作。
MaterialApp(
theme: ThemeData(
textTheme: TextTheme(button: TextStyle(fontSize: 30)), // Works
),
home: SomePage(),
)
正如 esentis 所说,您的Theme
小部件应该是您Scaffold
的父级。
这样做的原因是您的ScaffoldMessenger.of(context)
引用了后代Scaffold
,如其文档中所述:
管理后代[脚手架]的[小吃吧]。
但是由于您的Theme
不是Scaffold
的父级,因此它将考虑Scaffold
的主题,而不是您包裹FloatingActionButton
的主题。
您添加的Theme
位于小部件树的下方,因此Scaffold
不知道它的存在。
文档来源
编辑
当您调用Theme.of(builderContext).primaryColor
时,它正在工作,因为在当前builderContext
中,您可以访问由Theme
小部件更新的ThemeData
。
在ScaffoldMessenger.of(builderContext)
的情况下,builderContext
用于查找将用于访问您将在其中显示小吃栏的后代Scaffold
的ScaffoldMessengerState
。但是,当渲染SnackBar.content
时,它是一个没有style
属性的Text
小部件,它将应用小部件的默认行为,该行为在text.dart
源中实现如下:
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
TextStyle? effectiveTextStyle = style;
if (style == null || style!.inherit)
effectiveTextStyle = defaultTextStyle.style.merge(style);
以下是 Flutter Text 类 API 文档中的内容:
style
参数是可选的。省略时,文本将使用 从最近的封闭DefaultTextStyle
的样式。如果给定 样式的TextStyle.inherit
属性为 true(默认值),给定 样式将与最接近的封闭DefaultTextStyle
合并。这 合并行为很有用,例如,使文本加粗 使用默认字体系列和大小。
在这种情况下,由于style
属性null
它将使用DefaultTextStyle.of(context)
,但是在此小部件的context
(这不是您的builderContext
)中,它没有您的新ThemeData
因此它将应用基本。
这是一种无需移动Theme
小部件即可获得您想要fontSize
的方法,以证明我的观点:
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: Theme(
data: ThemeData(
textTheme: const TextTheme(button: TextStyle(fontSize: 50)),
),
child: Builder(builder: (builderContext) {
return FloatingActionButton(
onPressed: () {
final snackBar = SnackBar(
content: Text(
'SnackBar',
style: Theme.of(builderContext).textTheme.button, // Works
),
action: SnackBarAction(
label: 'Dismiss',
onPressed: () {},
),
);
ScaffoldMessenger.of(builderContext).showSnackBar(snackBar);
},
child: const Icon(Icons.slideshow),
);
}),
),
);
}
您还可以在DartPad上测试完整代码
在此代码中,我使用builderContext
定义我的Text
小部件的style
属性,该是Theme
的子项,因此它知道在此上下文中ThemeData
的变化,并且由于我的style
属性不为空,因此它不会依赖于defaultTextStyle
。
Theme
小部件应该是Scaffold
的父级,以覆盖此页面的主题。测试过它,它有效。