我为我的应用创建了以下主题:
ThemeData _buildDarkTheme() {
final baseTheme = ThemeData(fontFamily: "Sunflower",);
return baseTheme.copyWith(
brightness: Brightness.dark,
primaryColor: Colors.grey[800],
accentColor: Colors.grey[850]);
}
然后我按照以下方式将它应用到我的应用程序:
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: _buildDarkTheme(),
home: new Scaffold(
appBar: _buildAppBar(),
body: new Container(
color: Theme.of(context).accentColor,
height: double.infinity,
child: new ListView.builder(...
但是,当我尝试访问容器内部(或其他任何地方)的重点颜色而不是预期的Colors.grey [850]时,它默认为蓝色。此外,尝试使用自定义字体向日葵字体系列不起作用,但当我改为使用
new Text("Hello World", style: new TextStyle(fontFamily: "Sunflower"))
字体显示正确。
我是新手,因为任何解决这些问题的帮助都会受到欢迎。
答案 0 :(得分:7)
这与context
和Theme.of
的工作方式有关。
来自Theme类源代码:
static ThemeData of(BuildContext context, { bool shadowThemeOnly = false }) {
final _InheritedTheme inheritedTheme =
context.inheritFromWidgetOfExactType(_InheritedTheme);
if (shadowThemeOnly) {
if (inheritedTheme == null || inheritedTheme.theme.isMaterialAppTheme)
return null;
return inheritedTheme.theme.data;
}
final ThemeData colorTheme = (inheritedTheme != null) ? inheritedTheme.theme.data : _kFallbackTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final TextTheme geometryTheme = localizations?.localTextGeometry ?? MaterialTextGeometry.englishLike;
return ThemeData.localize(colorTheme, geometryTheme);
}
Theme.of
(和Navigator.of(),...
。of()等),查看传递它们的上下文,然后向上遍历窗口小部件树,寻找窗口小部件指定的类型。
现在,看看你的代码
Widget build(BuildContext context) {
return new MaterialApp(
theme: _buildDarkTheme(),
home: new Scaffold(
appBar: _buildAppBar(),
body: new Container(
color: Theme.of(context).accentColor,
您可以看到,context
传入Theme.of
的{{1}}实际上是您正在创建的主题之上的上下文。因此它无法找到您的主题并将恢复为默认值。这是因为窗口小部件树看起来有点像下图(忽略所有中间层,箭头指向您正在使用的上下文。
MyApp - context <--------
MaterialApp
Theme
Scaffold
有两种方法可以解决这个问题;第一种是使用Builder
类在具有主题下方的上下文的闭包内构建窗口小部件。这看起来像这样:
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: _buildDarkTheme(),
home: new Scaffold(
appBar: _buildAppBar(),
body: new Builder(builder: (context) => new Container(
color: Theme.of(context).accentColor,
height: double.infinity,
child: new ListView.builder(...
))
它会使树看起来像这样:
MyApp - context
MaterialApp
Theme
Scaffold
Builder - context <---------
另一个(首选)选项是将构建器的代码拆分为自己的类 - StatelessWidget
- 继承的类或StatefulWidget
和State
对。
答案 1 :(得分:1)
为什么不这样创建_darkTheme
变量:
ThemeData _darkTheme = new _buildDarkTheme();
然后用它来定义颜色?
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: _buildDarkTheme(),
home: new Scaffold(
appBar: _buildAppBar(),
body: new Container(
color: _darkTheme.accentColor,
height: double.infinity,
child: new ListView.builder(...
答案 2 :(得分:1)
在MaterialApp类中使用主题时,我遇到了同样的问题。如果您只希望整个Flutter应用程序具有一个主题,则只需在主页中使用一个主题(调用所有其他页面的主题)即可。
这样做之后,在其他页面中,请不要返回MaterialApp类,否则它将覆盖您的主题并使用默认主题。
这是我主页的代码:
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
fontFamily: "Test",
primaryColor: Colors.yellow,
buttonColor: Colors.yellow,
),
routes: {
'/': (BuildContext context) => AuthPage(),
},
);
然后,在AuthPage中,返回Scaffold而不是MaterialApp。