用 Flutter 在本地覆盖 CupertinoTheme
Locally overriding CupertinoTheme with Flutter
我正在使用 Cupertino 小部件,需要在本地覆盖我的全局 CupertinoTheme,并为此使用 CupertinoTheme
小部件。我的用例是在图像顶部显示文本时强制使用一些 'dark' 主题,但问题是普遍的。
在下面的示例中,我尝试更改一种文本样式的字体大小(从 42px 到 21px),但没有应用:两个文本具有相同的大小(第二个应该是 21px 高)。
好像CupertinoTheme.of(context)
没有读到覆盖的样式,与documentation
相反
Descendant widgets can retrieve the current CupertinoThemeData by calling CupertinoTheme.of
这是一个示例(可以在 DartPad 上测试):
import 'package:flutter/cupertino.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
debugShowCheckedModeBanner: true,
theme: CupertinoThemeData(
brightness: Brightness.dark,
textTheme: CupertinoTextThemeData(
navLargeTitleTextStyle: TextStyle(fontSize: 42)
)
),
home: Home()
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Column(
children: [
Text(
'Hello, World #1!',
style: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle
),
CupertinoTheme(
data: CupertinoThemeData(
textTheme: CupertinoTextThemeData(
navLargeTitleTextStyle: TextStyle(fontSize: 21)
)
),
child: Text(
'Hello, World #2!',
style:
CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle
),
),
]
)
);
}
}
您从错误的上下文中获取主题。上下文必须是 CupertinoTheme 小部件的后代(或者更确切地说是将从中创建的元素)。尝试:
CupertinoTheme(
data: ...,
child: Builder(
builder: (context) => ... CupertinoTheme.of(contex)...
)
)
通过构建方法的内容参数,您可以访问构建方法小部件的祖先所做的任何事情。无论您在构建方法中做什么都不会影响它。
小部件是用于创建元素树的配方。您在 build(er) 方法中获得的上下文参数是为该小部件创建的元素(的简化接口)。 Foo.of(context) 方法通常搜索上下文的祖先元素以查找 Foo。 (在某些情况下有缓存,所以它不是一个缓慢的搜索。)当你在构建方法中创建一个小部件树时,你只是在创建小部件;元素将在构建方法完成后创建。使用 Builder 小部件,就像我在上面所做的那样,延迟在 Builder 的 builder 参数中创建小部件,直到为 Builder(及其上方的小部件)创建元素之后。所以这是解决问题的一种方法。另一种方法是在您的代码中使用作为 CupertinoTheme 子级的小部件创建一个新的 StatelessWidget,因为它同样会延迟这些小部件的创建,直到创建该无状态小部件(及其父级)的元素之后。
我正在使用 Cupertino 小部件,需要在本地覆盖我的全局 CupertinoTheme,并为此使用 CupertinoTheme
小部件。我的用例是在图像顶部显示文本时强制使用一些 'dark' 主题,但问题是普遍的。
在下面的示例中,我尝试更改一种文本样式的字体大小(从 42px 到 21px),但没有应用:两个文本具有相同的大小(第二个应该是 21px 高)。
好像CupertinoTheme.of(context)
没有读到覆盖的样式,与documentation
Descendant widgets can retrieve the current CupertinoThemeData by calling CupertinoTheme.of
这是一个示例(可以在 DartPad 上测试):
import 'package:flutter/cupertino.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
debugShowCheckedModeBanner: true,
theme: CupertinoThemeData(
brightness: Brightness.dark,
textTheme: CupertinoTextThemeData(
navLargeTitleTextStyle: TextStyle(fontSize: 42)
)
),
home: Home()
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Column(
children: [
Text(
'Hello, World #1!',
style: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle
),
CupertinoTheme(
data: CupertinoThemeData(
textTheme: CupertinoTextThemeData(
navLargeTitleTextStyle: TextStyle(fontSize: 21)
)
),
child: Text(
'Hello, World #2!',
style:
CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle
),
),
]
)
);
}
}
您从错误的上下文中获取主题。上下文必须是 CupertinoTheme 小部件的后代(或者更确切地说是将从中创建的元素)。尝试:
CupertinoTheme(
data: ...,
child: Builder(
builder: (context) => ... CupertinoTheme.of(contex)...
)
)
通过构建方法的内容参数,您可以访问构建方法小部件的祖先所做的任何事情。无论您在构建方法中做什么都不会影响它。
小部件是用于创建元素树的配方。您在 build(er) 方法中获得的上下文参数是为该小部件创建的元素(的简化接口)。 Foo.of(context) 方法通常搜索上下文的祖先元素以查找 Foo。 (在某些情况下有缓存,所以它不是一个缓慢的搜索。)当你在构建方法中创建一个小部件树时,你只是在创建小部件;元素将在构建方法完成后创建。使用 Builder 小部件,就像我在上面所做的那样,延迟在 Builder 的 builder 参数中创建小部件,直到为 Builder(及其上方的小部件)创建元素之后。所以这是解决问题的一种方法。另一种方法是在您的代码中使用作为 CupertinoTheme 子级的小部件创建一个新的 StatelessWidget,因为它同样会延迟这些小部件的创建,直到创建该无状态小部件(及其父级)的元素之后。