When Should one use style: TextStyle() and Theme.of() - flutter

I am learning Flutter. Sometimes I see coders use
text: Text("text", style: TextStyle(color: kTextColor)
and sometimes they use
child: Text("text",
style: Theme.of(context).textTheme.bodyText1,
What is the difference between these two code snippets? And what does context mean?

in my opinion: in a big project it's good practice to define your theme first. Then, you implement it in your app. Therefore, I'd go with the second approach to define headlines and body texts and button texts.
Instead, when you want to personalize some text in your app a little you can use:
style: Theme.of(context).textTheme.headline5?.copywith(
// personalize even more, with exact the same properties of TextStyle
...
)
which copies everything in that textTheme besides the stuff you define in that block.
OF COURSE it makes sense to use TextStyle in some contexts, like when you want to quickly format some text that you know that it doesn't need refactoring at the moment you're writing it, i.e. you just want to style some text regardless of theming.

If you take a look at MainApp(), that used by main method. You can find something like this,
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
buttonTheme: ButtonThemeData(
textTheme: ButtonTextTheme.primary,
),
textTheme: Theme.of(context).textTheme.copyWith(
headline1: TextStyle(fontSize: 33, color: Colors.orange),
headline2: TextStyle(
fontSize: 12,
color: Colors.pink,
),
),
),
home: DropDOOO(),
);
}
So you can see there is a parameter call ThemeData. This will be used by default and when you will call Theme.of(). You can find textTheme here too.
Next one TextStyle(), you can override Texttheme using TextStyle() using it.
For more, visit
themes
TextTheme

Related

How to set multiple colors for text themes?

I try to make an app theme for the text style. I get from the flutter docs this example.
MaterialApp(
title: appName,
theme: ThemeData(
// Define the default brightness and colors.
brightness: Brightness.dark,
primaryColor: Colors.lightBlue[800],
// Define the default font family.
fontFamily: 'Georgia',
// Define the default `TextTheme`. Use this to specify the default
// text styling for headlines, titles, bodies of text, and more.
textTheme: const TextTheme(
displayLarge: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold),
titleLarge: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic),
bodyMedium: TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
),
),
home: const MyHomePage(
title: appName,
),
);
and
Container(
color: Theme.of(context).colorScheme.secondary,
child: Text(
'Text with a background color',
style: Theme.of(context).textTheme.titleLarge,
),
),
I want to have the option to add multiple colors for the same text size. For example, the titleLarge can be red or white.
Adding color in the TextTheme->TextStyle only gives the option to add one color.
Is there a way for me to change it later in the Text widget? Maybe a way to override color from Theme.of(context).textTheme.titleLarge?
You can copy the theme, then give individual text styles like this
Theme.of(context).textTheme.apply(bodyColor: Colors.white).titleLarge
or you can also use copyWith using conditional ? like this
Theme.of(context).textTheme.titleLarge?.copyWith(color: Colors.white)
or null check ! like this
Theme.of(context).textTheme.titleLarge!.copyWith(color: Colors.white)
You can override at the usage place with copyWith as following
Theme.of(context).textTheme.titleLarge!.copyWith(color: Colors.white)

Best practice to propagate theme through flutter screens

I've made a basic theme for my app and set it in the MaterialApp widget
ThemeData(
primaryColor: Colors.black,
backgroundColor: Colors.grey.shade50,
scaffoldBackgroundColor: Colors.grey.shade50,
buttonColor: Colors.purple,
);
but it seems the theme is not being updated on MaterialAppshome
home: LoginScreen()
. the button nor the background (supposed to be black and gray) aint updating...
What is the correct way of doing this?
As per the docs:
Using a Theme
Now that you’ve defined a theme, use it within the widgets’ build() methods by using the Theme.of(context) method.
The Theme.of(context) method looks up the widget tree and returns the nearest Theme in the tree. If you have a standalone Theme defined above your widget, that’s returned. If not, the app’s theme is returned.
In fact, the FloatingActionButton uses this technique to find the accentColor.
Container(
color: Theme.of(context).accentColor,
child: Text(
'Text with a background color',
style: Theme.of(context).textTheme.headline6,
),
),

How to set the SliverAppBar's Title style from the MaterialApp's theme parameter?

If I would like to set the style of a regular appbar title from the MaterialApp theme parameter, I would do the following:
ThemeData(appBarTheme: const AppBarTheme(
textTheme: TextTheme(
headline6: TextStyle(
color: Colors.red,
fontWeight: FontWeight.w600,
fontSize: 37,
),
),
),
However, I can't seem to figure out how to do the same thing for a SliverAppBar. I am aware that you can simply set the style of the Text widget assigned to the title parameter within the SliverAppBar widget, but I'm trying to see if I can achieve the same result from the app's custom theme instead.

How to set textStyle of a Cupertino app in flutter

I have a CupertinoApp and I would like to apply a custom TextStyle to all the screen/object of my app. For example I would lie to set a font family to all Text widget & Dialog widget and use that font across all my app. I was hoping to set it once in CupertinoThemeData or CupertinoTextThemeData but so far I did not have joy.
Note: I am able to set style for each Text however I would like to set it once for all
I've just run into this at the moment.
All I'm trying to do is colour text white, with general black backgrounds across the app (not font work).
The following has brought me some success:
return CupertinoApp(
theme: new CupertinoThemeData(
brightness: Brightness.dark,
primaryColor: CupertinoColors.dark,
barBackgroundColor: CupertinoColors.black,
scaffoldBackgroundColor: CupertinoColors.black,
textTheme: new CupertinoTextThemeData(
primaryColor: CupertinoColors.white,
brightness: Brightness.light,
textStyle: TextStyle(color: CupertinoColors.white),
// ... here I actually utilised all possible parameters in the constructor
// as you can see in the link underneath
),
),
// ...
)
Ref: CupertinoTextThemeData Constructor
I think you could extend my TextStyle(color: CupertinoColors.white) to apply fonts too. I intend to extract the TextStyle and ...ThemeData into separate classes to create a single place to edit them.
Hopefully this advances your position
Use this example of theme in your CupertinoApp .
theme: CupertinoThemeData(
textTheme: CupertinoTextThemeData(
textStyle: TextStyle(
fontSize: 14,
fontStyle: FontStyle.italic,
backgroundColor: CupertinoColors.black)),
),
Reminder : For the colors, use a CupertinoColor instead of a simple
Color.
My code is here

How to set color of all text in a specific container in flutter?

I don't want to change the text color of the whole app. Just all the text inside a container. Can I wrap it with some other widget or something for this ?
To apply certain TextStyle properties only to a subtree of your app. You can use DefaultTextStyle
DefaultTextStyle(
child: Container(child: /* your subtree */),
style: TextStyle(color: Colors.red),
),
as a comment pointed out, this replaces all defaults, not just the color. This can be mitigated by using the merge constructor:
DefaultTextStyle.merge(
child: Container(child: /* your subtree */),
style: TextStyle(color: Colors.red),
),
flutter's answer is good in my opinion. But the power of ThemeData is more than you think. Here is the official documentation about Themes for part of an application.
You could provide a Theme to wrap your container to provide a new theme. Here is two way to slove it:
1. Creating unique ThemeData
/*Not recommended, this could make a totally different If you just want a little part changed.*/
Theme(
// Create a unique theme with "ThemeData"
data: ThemeData(
textTheme: /* Your Text Theme*/,
),
child: Container(
onPressed: () {},
child: Text("Your Text Here"),
),
);
2. Extending the parent theme
Theme(
// Find and extend the parent theme using "copyWith". See the next
// section for more info on `Theme.of`.
data: Theme.of(context).copyWith(textTheme: /* Provide your theme here! */),
child: Container(
child: Text("your text here"),
),
);
You could also use existed theme with a little changed:
Theme.of(context).textTheme.copyWith(
body1: Theme.of(context).textTheme.body1.copyWith(color: Colors.red),
)
Use DefaultTextStyle.merge to keep your theme and just change the color.
DefaultTextStyle.merge(
style: TextStyle(color: Colors.grey[400]),
child: Column(...),
)
If you are using the MaterialApp widget you could use the theme property of it and set different Text themes and call them anywhere in your app. For example the following code defines 3 different text themes:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Time Tracker",
theme: ThemeData(
textTheme: TextTheme(
headline: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold,color: Colors.blue),
title: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic,color: Colors.red),
body1: TextStyle(fontSize: 14.0, fontFamily: 'Hind',color: Colors.yellow),
),
),
home: LandingPage(),
);
}
}
You can then call a particular theme(headline) anywhere in your app like this:
Text('Home Page',style: Theme.of(context).textTheme.headline,)
Which gives you the headline TextTheme
I have functions for all my styles
TextStyle largeTextStyle() => TextStyle(fontSize: 150);
then I just do
Text("blah", style:largeTextStyle())