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.