The Style in Flutter
An in-depth look at the TextStyle Widget
We’re going to use the good ol’ startup app (the counter app) as a means to examine and demonstrate the TextStyle widget in this article. However, I’ve removed almost everything of the original code leaving just the sentence, ‘You have pushed the button this many times:’ The idea being, we’ll then introduce options in this article modifying ‘the style’ of the text and get an appreciation of what the TextStyle widget can do for you and your own apps. A screenshot of the ‘stripped down’ counter app with now no style explicitly defined at all is presented below.
I Like Screenshots. Tap Captions For Gists.
As always, I prefer using screenshots in my articles over gists to show concepts rather than just show code. I find them easier to work with frankly. However, you can click or tap on their captions to see the code in a gist or in Github. Tap or click on the screenshots themselves to zoom in on them.
Let’s begin.
Now, it turns out with no theme explicitly provided, you’ll find that sentence suddenly appearing with its text large, red, and underlined in yellow in front of a black background. See below. As it happens, I’ve removed the Scaffold widget from the example app, and, along with its more obvious contributions, it also provides a theme.
However, I still want to keep the code to a minimum and just concentrate on the ‘text style’ aspect of the app. And so, another approach is to provide the widget, Material, instead. It’s a StatefulWidget, and you can see its build() function (screenshot below) when no ‘textStyle’ is provided, a pre-defined style, bodyText2, is utilized resulting in an albeit more humble theme as seen in the screenshot below on the far right.
By the way, the first screenshot below is of that horrific red and yellow text style. It's a ‘high level’ variable defined near the beginning of the library file, app.dart. As you see in the second screenshot, it’s literally passed as the app’s text style. Your own app’s home screen will be a subtree of this app, and if you don’t define a style for your home screen and such, that’s the text style you get. As stated in the code’s documentation, it’s to encourage developers to explicitly specify a style.
The Parameters Of Style
Below, is a listing of all the parameters that make up the TextStyle widget. At a glance, you can readily tell this widget is all about style and presentation.
Inherit Style
The first named parameter, inherit, is used to determine how the described style will be passed along to a Text widget in particular. The Text widget, of course, has the named parameter, style, that takes in a TextStyle object, but uses the ‘DefaultTextStyle’ object if the style parameter is null. If passed in, the TextSytle object is ‘merged’ with the ‘DefaultTextStyle’ object but only if the TextStyle object’s ‘inherit’ property is set to True. If false, the ‘default text style’ is merely replaced with the provided TextStyle object.
Color Front and Back
The next two parameters are relatively straight forward: color and backgroundcolor. Two examples are listed below. The first has the text displayed in red. The next example has the background of the text in blue:
1) child: const Text('You have pushed the button this many times:',
style: const TextStyle(
color: Colors.red,
)),
2) child: const Text(
'You have pushed the button this many times:',
style: TextStyle(backgroundColor: Colors.blue),
),
The Color of Text
The default color for text in Flutter is black. Again, a list of pre-defined constant values is made available to you to assign to the parameter, color. Further below, is the file, colors.dart, with many of these values.
In Flutter, you’ve got colors. Man, do you have colors! What’s more, each individual color can be assigned a further variance — either how pale the color is or how dark the color is. You’re offered ten different shades of each color.
How Opaque is Your Text
You can further adjust the opacity of an individual color — how transparent the color is. Each Color object has the withOpacity() function that takes in a double value between 0.0 to 1.0.
Far from final, they have one additional color called, transparent. One could say it’s not a color at all as it’s completely invisible. Ironically, it’s the first constant defined in the class, Colors.
Size It Up
Now, your choice of colors was ridiculous, but now let’s talk text size. Font sizes are calculated automatically by Flutter based on the device’s OS setting. The default size of the text in Flutter is 14 (in logical pixels). Of course, you can decrease or increase that value. As part of Flutter’s accessibility support, very large fonts are made available. You can see below, the TextStyle widget’s fontSize parameter takes in a double numeric value to specify size.
The specified size is further multiplied by the current textScaleFactor (traditionally 1.0). This implies your text can be any size you imagine. Whether it’s readable to the intended user — that’s on you. For example, it’s been noted in Muhammed Salih Guler’s free article, A deep dive into Flutter’s accessibility widgets, explicitly assigning the textScaleFactor may interfere with any accessibility widgets you may have implemented as well. (Thanks to Scott Stoll for that tidbit)
Of course, with the TextStyle widget, you can do some rudimentary things like setting the text to bold or to italic:
The observant reader will note the two styles are dictated by two different named parameters, fontWeight, and fontStyle — allowing your text to be both bold and italic. You’ll find most of the TextStyle widget’s parameters take in a list of pre-defined constant values. For instance, such values for both the fontWeight and fontStyle parameters are found in the file, text.dart.
Giving Some Space
You can specify the amount of space (in logical pixels) between each letter. Note, a negative value will bring the letters closer together.
wordSpacing
The amount of white-space (in logical pixels) between each word can also be specified. Again, a negative value brings the words closer together.
textBaseline
In Flutter, there are two enum settings for the parameter, textBaseline. They are alphabetic and ideographic. The default to alphabetic.
“The alphabetic baseline is the line that the letters in alphabets like English sit on. You can see that the English letters sit nicely on the line, but it cuts through the Chinese characters. When you use the ideographic option, though, the baseline is at the bottom of the text area. Note that the Chinese characters don’t actually sit right on the line. Rather, the line is at the very bottom of the text line.” — What is the difference between alphabetic and ideographic in Flutter’s TextBaseline enum (source: stackoverflow.com )
height
By default, the height of the text is simply defined by the font size. The height parameter allows you to manually adjust that height as a multiple of the font size.
What’s Your Locale?
Rarely used, but if required, this allows you to preserve the text characters to a specific region in the World. For example, conveying a price using the denomination of a particular region while the rest of the interface remains local. Would have to implement localization in this simple example to demonstrate this, and so I’ll leave it to your imagination.
What’s In The Foreground?
This parameter takes in a Paint object. In other words, the text is ‘painted’ on the screen. Of course, this allows you to get rather elaborate. For example, the text could be given a gradient color — gradually changing from one color to another. Note, the parameter, color, must be null for this to work. These two parameters are mutually exclusive (you can’t use both). This is also true with the parameters, backgroundColor, and background. Either one or the other.
The Shadow Knows!
You can literally add an array of shadowing to your text with the named parameter, shadows. It takes in…well,…an array of shadows. The example below has two shadows: one green; one red. The bigger the blur radius, the more blurry. The bigger the offset, the farther the shadow from the lettering.
There are Font Features
A Flutter developer named, Suragch, wrote a great article essentially dedicated to the named-parameter, fontFeatures. It’s far better than I could do here. The link’s below.
Decorative Text
The named parameter, decoration, involves where ‘a line’ is placed along with the displayed text. There are four pre-defined ‘locations.’ The last three are demonstrated in screenshots further below.
Decorative With Style
There are another five pre-defined settings on not ‘where’ the line is presented but on ‘how’ the line is presented alongside the displayed text. This involves the next named parameter called, decorationStyle. See below.
The Thick Of It
The thickness of the decoration is based on the font size. However, you have the parameter, decorationThickness, to vary the thickness independent of the font’s own definition.
Label Your Development
The parameter, debugLabel, is for tracing the text style back through you app. The ‘style’ of your app’s text is traditionally ‘carried along’ in a number of ways: merging, copying, modifying, or interpolating — using one or more of the following four functions: merge(), copyWith(), apply(), or lerp(). Hence, while debugging and developing the assert () function is used in all four functions to record ‘how’ the current style was brought about.
The Font Family
The next parameter is called, fontFamily. All in all, the default fonts depends on the device’s operating system. With all being equal, however, the default font of the MaterialApp design interface is a Google font, ‘roboto.’ For Cupertino (iOS), the default font is ‘San Francisco’ font. By the way, the ‘fallback font’ (if there’s NO font provided at all) is Monospace:
A Family Package
The last parameter in the TextStyle widget is called package, and is used when a ‘font family’ is explicitly supplied to the Flutter app in a particular Dart package.
Google Font Family
It’s been recommended to me twice now to utilize Google’s own package, google_fonts, for all the fonts I may need. At last count, they’re up to 977 fonts, and I’ve incorporated them into my example app for your review.
There Is A General Theme
Finally, there are some thirteen ‘text themes’ made available to you. Your app’s ‘theme’ State object has the property, textTheme, with its finite list.
I’m afraid you will have to provide a ‘text theme’ whether with a Scaffold widget the implies one or by explicitly specifying the style with the TextStyle widget. Otherwise, it’s all black, red and yellow.
Cheers
*Source code as of November 02, 2020 +Source as of November 20, 2020