[英]How to set color of all Text widgets under a widget in Flutter?
According to this answer , all I have to do is to wrap a widget with Theme
and provide ThemeData
.根据这个答案,我所要做的就是用Theme
包装一个小部件并提供ThemeData
。 I return a widget from build
method as below:我从build
方法返回一个小部件,如下所示:
Theme( // wrapping `Card` widget with a theme
data: Theme.of(context).copyWith( // extend main theme
textTheme: Theme.of(context).textTheme.copyWith( // extend main text theme
subtitle1: TextStyle(
color: Colors.white, // subtitle text color to white
),
caption: TextStyle(
color: Colors.white, // caption text color to white
),
),
),
child: Card( // card widget as a child of theme
// ... other stuff ...
child: Container(
margin: _margin,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
profile.alias,
style: Theme.of(context).textTheme.subtitle1, // set text style to subtitle1
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Joined ${timeago.format(profile.dateJoined)}',
style: Theme.of(context).textTheme.caption, // set text style to subtitle2
textAlign: TextAlign.right,
),
Text(
'Has ${profile.stats.subscriberCount == null ? 0 : profile.stats.subscriberCount} subscribers',
style: Theme.of(context).textTheme.caption, // set text style to caption
textAlign: TextAlign.right,
),
Text(
'Following ${profile.stats.followingCount == null ? 0 : profile.stats.followingCount} people',
style: Theme.of(context).textTheme.caption, // set text style to caption
textAlign: TextAlign.right,
),
],
),
),
],
)),
),
);
Oddly, this doesn't affect my text anyway.奇怪的是,这不会影响我的文字。 It still stays black.它仍然保持黑色。
Probably there is something I don't understand about the themes.可能有一些我不明白的主题。 Is there a way to partially apply a theme (in this case, text color) to a widget that affects all direct and indirect children?有没有办法将主题(在本例中为文本颜色)部分应用到影响所有直接和间接子级的小部件?
Here is an example of how to use the global theme and local theme using Theme()
to particular widgets.这是一个示例,说明如何使用Theme()
对特定小部件使用全局主题和本地主题。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// Global Theme
primarySwatch: Colors.blue,
textTheme: Theme.of(context).textTheme.copyWith(
bodyText2: TextStyle(
color: Colors.orangeAccent,
fontWeight: FontWeight.bold,
),
),
cardTheme: CardTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
color: Colors.blueGrey),
),
home: Scaffold(
appBar: AppBar(
title: Text("List Builder"),
),
body: HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Center(child: Text("Using MaterialApp theme")),
Expanded(
child: ListView.builder(
itemCount: 4,
itemBuilder: (context, index) {
return Theme(
// Child Theme
data: Theme.of(context).copyWith(
textTheme: TextTheme(
bodyText2: TextStyle(color: Colors.greenAccent),
),
cardTheme: CardTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
color: Colors.red,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Card(
// Card Theme of Theme() data
child: Container(
width: MediaQuery.of(context).size.width * 0.4,
height: MediaQuery.of(context).size.height * 0.1,
child: Center(
child: Text(
"Hello (Using Theme())",
),
),
),
),
Container(
width: MediaQuery.of(context).size.width * 0.4,
height: MediaQuery.of(context).size.height * 0.1,
child: Card(
// Card Theme of MaterialApp
child: Center(
child: FittedBox(
child: Text(
"Welcome(card theme from MaterialApp)",
style: Theme.of(context).textTheme.bodyText2,
),
),
),
shape: Theme.of(context).cardTheme.shape,
color: Theme.of(context).cardTheme.color,
),
),
],
),
);
},
),
),
],
);
}
}
TL;DR: Use Builder
as a child of Theme
if you'd like to apply the theme to all children. TL;DR:如果您想将主题应用于所有子项,请将Builder
用作Theme
的子项。
So, my code above seems to be using the context of build
method, which is of parent.所以,我上面的代码似乎使用了build
方法的上下文,它是父级的。 It changes the theme of the direct child of Theme
.它改变了 Theme 的直接孩子的Theme
。 This is quite counter-intuitive but luckily there is a way to initialize a brand new BuildContext
using Builder
widget.这是非常违反直觉的,但幸运的是,有一种方法可以使用Builder
小部件初始化全新的BuildContext
。
So, if you want to apply the theme to all children whether they are direct or undirect children , always use Builder
as a direct child of Theme
.所以,如果你想将主题应用到所有孩子,无论他们是直接孩子还是非直接孩子,总是使用Builder
作为Theme
的直接孩子。
Theme(
data: // your theme data here
child: Builder(
builder: (context) => // this is where you do stuff
)
)
Notice how Builder
provides a BuildContext
named context
?注意Builder
如何提供一个名为context
的BuildContext
? This is a brand new context to work with and actually contains subtheme that we have just created rather than the context
that is provided by build
method.这是一个全新的上下文,实际上包含我们刚刚创建的子主题,而不是build
方法提供的context
。 So, when you create a Text
widget under Builder
widgeet somewhere:因此,当您在某处的Builder
小部件下创建Text
小部件时:
// under Builder widget somewhere
Text(
'my text',
style: Theme.of(context).textTheme.caption // we have a context here
)
The context
here uses the context provided by Builder
widget, not the build
method, which makes it intuitive.这里的context
使用的是Builder
小部件提供的上下文,而不是build
方法,这使它直观。
Also, the reason I use Theme.of
is because I'd like to extend main theme, not create an empty theme .另外,我使用Theme.of
的原因是因为我想扩展主主题,而不是创建一个空的主题。 And Flutter has many predefined styles for texts such as bodyText1
, bodyText2
, heading1
(up to 6), caption
etc. and I can use it with this method.并且 Flutter 有许多预定义的 styles 文本,例如bodyText1
, bodyText2
, heading1
(最多6个), caption
等,我可以用这种方法使用它。
This is, at least, how I have solved the issue and the code makes sense.至少,这是我解决问题的方式,并且代码是有意义的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.