text主题属性在使用主题小部件时不起作用



我使用以下代码更改SnackBarActionfontSize

最少的可重现代码:

@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用于查找将用于访问您将在其中显示小吃栏的后代ScaffoldScaffoldMessengerState。但是,当渲染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的父级,以覆盖此页面的主题。测试过它,它有效。

相关内容

最新更新