Issue
The docs say that the brightness property sets:
The overall theme brightness.
The default TextStyle color for the textTheme is black if the theme is constructed with Brightness.light and white if the theme is constructed with Brightness.dark.
And that Theme:
Applies a theme to descendant widgets.
But I can't seem to change the brightness of child text widgets by wrapping them in a Theme
, and I don't understand why. Here's an example (using Flutter 2.5.2):
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.blue,
),
home: SafeArea(
child: Scaffold(
body: Column(
children: [
Text(
"This should be white"
),
Theme(
data: ThemeData(
brightness: Brightness.light,
primaryColor: Colors.blue,
),
child: Text(
"This should be black"
)
)
],
)
),
),
);
}
}
This produces:
Can someone explain why the bottom text isn't black, and how I can change the brightness of a specific text widget using theme brightness?
Solution
If you take a look at the implementation of the Text
widget you can see that its effectiveTextStyle
is based on the value of DefaultTextStyle.of(context)
text.dart:
class Text extends StatelessWidget {
// ...
@override
Widget build(BuildContext context) {
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
TextStyle? effectiveTextStyle = style;
if (style == null || style!.inherit)
effectiveTextStyle = defaultTextStyle.style.merge(style);
// ...
}
}
Also the documentation of DefaultTextStyle
says the following:
The text style to apply to descendant Text widgets which don't have an explicit style.
This default style is based on the theme data provided by MaterialApp
this is why your text is still white.
Instead of overriding with Theme
you can directly override the DefaultTextStyle
to obtain the result you want:
DefaultTextStyle(
style: TextStyle(color: Colors.black),
child: Text("This should be black"),
)
You want to use Theme
to change the TextStyle
of pre-made material widgets such as ListTile
for example which are not relying on DefaultTextStyle.of(context)
:
Theme(
data: ThemeData.light().copyWith(brightness: Brightness.light),
child: const ListTile(title: Text('This should be black')),
),
Under the hood ListTile
is exactly doing what is shown above when rendering its title
widget (it is using AnimatedDefaultTextStyle
which works the same as DefaultTextStyle
):
list_tile.dart
// This is what you can find inside the build method
final TextStyle titleStyle = _titleTextStyle(theme, tileTheme);
// As you can see the default style is overrided with the value
// from _titleTextStyle
final Widget titleText = AnimatedDefaultTextStyle(
style: titleStyle,
duration: kThemeChangeDuration,
child: title ?? const SizedBox(),
);
Try the full example on DartPad
Answered By - Guillaume Roux
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.