Flutter: RichText with darktheme - flutter

I use some RichText throughout my application to switch colors between text and display widgets in between.
E.g.
RichText(
text: TextSpan(text: 'text1', style: TextStyle(color: Colors.black),
children: [
WidgetSpan(alignment: PlaceholderAlignment.middle, child: SomeWidget()),
TextSpan(text: 'text2', style: TextStyle(color: Colors.blue),
WidgetSpan(alignment: PlaceholderAlignment.middle, child: Icon(Icons.someIcon)),
TextSpan(text: 'text3'),
]
));
The problem now is that when switching to dark mode, the black test is contrasted to a black background and thus invisible. The regular Text('some text') widget will automatically display black by default but will become white in dark mode. How can I achieve the same or something similar when using RichtText?

Well you defined your RichText like this:
TextSpan(text: 'text1', style: TextStyle(color: Colors.black)
As you know the color argument that you pass to a Widget has the highest priority, therefore, your TextSpan will always be black.
One solution is instead of hardcoding the color you can do this:
Theme.of(context).textTheme.bodyText2?.color
If we look at the definition of this theme it looks like this:
/// The default text style for [Material].
TextStyle? get bodyText2 => bodyMedium;
If you use this approach your TextSpan and normal Text widgets should have the same color. In general one should always prefer working with themes over hardcoding colors. If your user switches to dark mode the theme will switch too and therefore, all styles should be switched correctly as well.

Related

Flutter - Text with space breaks background color

Text with whitespace and background color does not apply the background color for the whitespace part.
Please see the following screenshot:
I would expect the whitespace to be colorized with a red background as well, instead, it increases the width of the parent container without applying the background color.
Here is a live playground link
Question:
Is there a way to fix this?
Seems like all spaces on right has been removed for nth(i don't know yet) reason, Currently I am able to solve with RichText with adding extra transparent char.
Container(
color: Colors.blue,
child: Text.rich(
TextSpan(
text: "hi ",
style: TextStyle(
backgroundColor: Colors.red,
fontSize: 250.0,
),
children: [
TextSpan(text: "a", style: TextStyle(color: Colors.transparent))
],
),
)),
It takes extra single space,
One thing You can do is set text background color to transparent and give the main color to container.

Change text style based on search bar text

I would like to change the style of the text according to what I enter in the search bar, that is, search if it matches and change dynamically. Something like that.
Example image
Use RichText to specify different styles for each text segment:
RichText(text: TextSpan(children: [
TextSpan(text: 'Hello', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ' world!'),
]));

ExpansionTile Title color changes on expansion

ExpansionTile(
title: Text('test'),
children: [Text('test expanded')],
),
In this simple test, when I click on the title to expand the widget, the original title text turns from black to grey. I'm not sure if this is a Theme issue (I tried changing every grey color to something bright) or is something that I can manage through ExpansionTile (don't see it in the hover menu).
I did find that I could explicitly state the text color should be black and then it stays constant. However, in my real world use case for this tile I have several Text widgets and don't want to have to color each one.
Any ideas on how to address this in one shot?
It is an animated color between accentColor & subtitle1 color. So, you can override theme like this.
Theme(
data: ThemeData(
accentColor: Colors.black,
textTheme: TextTheme(
subtitle1: TextStyle(color: Colors.black),
),
),
child: ExpansionTile(
title: Text('test'),
children: [Text('test expanded')],
),
),

Flutter RichText is not showing

I have a regular normal rich text widget in a Centered per https://api.flutter.dev/flutter/widgets/RichText-class.html within a Scaffold. I can't see it. I can't see anything. The debug tools show that the Rich Text is indeed there in the widget heirarchy (though I can't see the TextSpans within it, presumably they're in there.)
Scaffold(body: Center(child:
RichText(
text: TextSpan(
text: 'Hello ',
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ' world!'),
],
),
),
));
I tried an android build to see whether this was a bug specific to linux desktop builds. It wasn't! It's happening here too. However, the contrast ratio of my phone is high enough that I can just barely see the text in there, White on Off White. It turns out that, unlike the Text widget, the default color for RichText text is white, same as the theme's background, so the text wont be visible.
(Is it possible the app is responding to the system-wide dark mode theme? Nope. Switching theme doesn't affect anything.)
So, WHY is this the default color? Because DefaultTextStyle is bad and wrong I guess? Use Theme.of(context).textTheme.bodyText1 and you will get the results you expect.
RichText is a basic, lower-level approach to rendering text and intentionally does not use theme styles.
However, Text.rich does:
Scaffold(body: Center(
child: Text.rich(
TextSpan(
text: 'Hello ',
children: <TextSpan>[
TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ' world!'),
],
),
),
));

Set horizontal alignment in MaterialBanner in Flutter

I'm trying to set a layout inside MaterialBanner. I need to set the red-colored widget in the bottom to the left. However, I cannot figure it out how and the square widgets are always right-aligned.
Here is my sample code.
If you know how to implement it, I would like to know the tip. Thank you.
MaterialBanner(
forceActionsBelow: true,
actions: <Widget>[
RaisedButton( // Tried Row, Expanded Widget but neither works
child: Text('Red'),
color: Color(0xff49A9EF),
),
RaisedButton(
child: Text('Blue 1'),
color: Color(0xff49A9EF),
),
RaisedButton(
child: Text('Blue 2'),
color: Color(0xff49A9EF),
),
],
content: Text(
'text text text text text text text text text text text text text text text text text text ',
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
...
)
I've tried this and I can answer why the Red Box doesn't move to the left.
The actions list of Widgets is always set to AlignmentDirectional.centerEnd so there is no way you can place a Widget in the actions list and expect it to be elsewhere.
What if the red box was passed to the leading property of the MaterialBanner Widget. Then we see that the box aligns on the top left with the provided content. Even when the padding is stripped off completely from the leading Widget it sticks to the top left.
Any reason why you wouldn't write a custom Widget to accomplish this ?