Create custom TextStyle class on Flutter - flutter

How can I create a custom TextStyle class in flutter? For example I have several buttons and want the text inside to all be the same fontSize and color but I don't want to repeat the TextStyle inside of each Text widget, but instead create something such as CustomTextStyle that I could use in the place of the TextStyle itself.
Is there a way to do this?

Create a separate class names CustomTextStyle and add the styles inside them like:
class CustomTextStyle {
static const TextStyle nameOfTextStyle = TextStyle(
fontSize: 24,
color: Colors.green,
fontWeight: FontWeight.bold,
);
}
Now you can use it in Text widget like:
Text('Lorem Ipsum',
style: CustomTextStyle.nameOfTextStyle,
)

To define your button or text style globally, you need to use theme.
For example, you can define a custom theme for TextButton :
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(
theme: ThemeData(
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
textStyle: MaterialStateProperty.all(
const TextStyle(fontSize: 20),
),
),
),
[...]

There are three ways to do this:
Using Theme:
You can declare multiple TextStyles separately in Theme based on widgets, for e.g. AppBar's TitleTextTheme, AppBar's ToolbarTextTheme, Button's TextTheme, General TextTheme for the whole app, or based on ThemeMode, for e.g. Dark Mode or Light mode, you can combine these two Widgets based and ThemeModes based as well.
To do this, Create a class called ThemeModel for example, Create the ThemeData Variables in it in which you'll declare these TextThemes and use it in your MaterialApp in main.dart as
MaterialApp(
...,
theme: ThemeModel().lightMode,
darkTheme: ThemeModel().darkMode,
)
Using a Custom Text Widget.
const CustomText extends StatelessWidget {
final String text;
const CustomText(this.text, {Key? key}): super(key:key);
#override
Widget build(BuildContext context) {
return Text(
text,
style: TextStyle(
color: YourColor,
fontSize: YourSize,
fontWeight: YourFontWeight
),
);
and use it as,
ElevatedButton(
onPressed: (){},
child: CustomText('Click Me'),
)
This way the TextStyle will remain same wherever you'll use this widget.
Using Custom TextStyle:
class CustomTextStyle {
static const TextStyle textStyle = TextStyle(
color: YourColor,
fontSize: YourSize,
fontWeight: YourFontWeight
);
}
and, use it as:
ElevatedButton(
onPressed: (){},
child: Text('Click Me',
style: CustomTextStyle.textStyle,
),
)
Hope, you understand that every one of these methods have their own utility and can be customized way further to make your app development easy.

Related

How can I Allow a user to change font in Flutter App?

I'm wanting to allow my users to have more customization in the UI of our app. Currently, our app is set up using ThemeData and Google Fonts.
I've implemented a simple dropdown to allow a user to select a font. How can I then take that selected font and change all fonts globally?
Main road block I'm finding it that I only want to change the font in TextStyle and not fontWeight / fontSize etc. I can save the user's selection via shared preferences or to the users collection on Firebase, but then how can I change .roboto to the selected choice.
Example of how I currently use Google Fonts (my current font is Roboto)
AutoSizeText(
AppLocalizations.of(context)!.newNote,
style: GoogleFonts.roboto(
textStyle: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
maxLines: 1,
),
Let me know if you need more explenation.
You can implemnent it similar to the themeMode setting in the new Flutter app skeleton. Something like this, only changing fontFamily as an example:
class MyApp extends StatelessWidget {
const MyApp({
super.key,
required this.settingsController,
});
final SettingsController settingsController;
#override
Widget build(BuildContext context) {
// The AnimatedBuilder Widget listens to the SettingsController for changes.
// Whenever the user updates their settings, the MaterialApp is rebuilt.
return AnimatedBuilder(
animation: settingsController,
builder: (BuildContext context, Widget? child) {
final themeData = ThemeData(
fontFamily: settingsController.fontFamily, // for example GoogleFonts.roboto().fontFamily
);
return MaterialApp(
theme: themeData,
// ...
The SettingsController class should implement ChangeNotifier and call notifyListeners() when the user changes font.
Se this post on how to use Roboto in a TextTheme: https://stackoverflow.com/a/64271758/20444

How to edit the flappy_search_bar flutter package?

I want to edit some features of the flappy_search_bar
As you see see the loading spinner is blue and I can't seem to edit this to any alternate color. I also am unable to edit the cursor color which is also blue.
Here is a copy of my current code block:
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SearchBar<Post>(
searchBarPadding: EdgeInsets.symmetric(horizontal: 20),
headerPadding: EdgeInsets.symmetric(horizontal: 10),
listPadding: EdgeInsets.symmetric(horizontal: 10),
onSearch: _getALlPosts,
hintStyle: TextStyle(color: Colors.black87),
hintText: 'Search',
iconActiveColor: Colors.deepPurpleAccent,
// cursorColor: Colors.deepPurpleAccent,
// loader: Colors.deepPurpleAccent,
textStyle: TextStyle(
fontFamily: 'OpenSans',
fontSize: 18.0,
),`
So far, I have tried editing directly within the search bar as seen above, adding extension code as follows:
class Styling extends SearchBar {
Styling(this.cursorColor);
final Color cursorColor;
static const accentColor = Colors.deepPurpleAccent;
#override
Widget build(BuildContext context) {
return Theme(
// data: Theme.of(context).copyWith(
// cursorColor: Theme.of(context).accentColor,
// ),
);
}
}
I have also tried editing the package files directly but this hasn't been a success either.
Has anyone suggest how to edit the cursor color and loading spinner color of the flappy_search_bar package?
I've been trying to do this too and managed to get it done.
To edit your cursor, apply the following to your top level MaterialApp under ThemeData :
cursorColor: Colors.red,
cupertinoOverrideTheme: CupertinoThemeData(
primaryColor: Colors.red,
),
This sets the color of the Cursor in ALL TextFields , I don't know how to edit it just for the TextField in the flappy_search_bar widget
For the loading indication, add this under the SearchBar you're using:
SearchBar<SomeClass>(
....
loader: const Center(child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(Colors.red))),
....
);
This is what the widget does internally if you look at the source.
Change Colors.red to whatever color you need.
Hope that helps.

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())

Flutter - How to change IconButtons size with Theme

I have a Row with multiple IconButtons and I need to change their color and size.
I managed to change the color, but I'm not able to change the icons size.
IconTheme(
data: IconThemeData(size: 48.0, color: Colors.yellow),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.delete),
onPressed: () => null,
),
IconButton(
icon: Icon(Icons.file_upload),
onPressed: () => _addPhoto(false),
),
IconButton(
icon: Icon(Icons.camera_alt),
onPressed: () => _addPhoto(true),
),
],
),
),
If I set the size within the IconButtons with iconSize it works, but with IconTheme it doesn't.
How can I fix it?
As defined in the official docs, link here:
This property must not be null. It defaults to 24.0. The size given here is passed down to the widget in the icon property via an IconTheme. Setting the size here instead of in, for example, the Icon.size property allows the IconButton to size the splash area to fit the Icon. If you were to set the size of the Icon using Icon.size instead, then the IconButton would default to 24.0 and then the Icon itself would likely get clipped.
Therefore, IconButton needs to be given the iconSize property as this overrides the IconTheme size property. If you want your button to have size derived from IconTheme then you should make your custom IconButton which sets the iconSize for you. For example:
class CustomIconButton extends StatelessWidget {
CustomIconButton({Key key, this.onPressed, this.icon});
final Function onPressed;
final Icon icon;
#override
Widget build(BuildContext context) {
IconThemeData iconThemeData = IconTheme.of(context);
return IconButton(
onPressed: onPressed, iconSize: iconThemeData.size, icon: icon);
}
}
Use iconTheme of ThemeData like so and all your icons will be size 35 with the below code:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
iconTheme: IconThemeData(
size: 35.0,
),
),
home: HomePage(),
);
}
}
First, check if you are in a layout area that uses the primary or default theme. Whats that? Places on a layout that uses the primary color.
ThemeData(
primaryColorLight: Colors.blueAccent[100],
primaryColor: Colors.blueAccent[200],
primaryColorDark: Colors.blueAccent[700],
accentColor: Colors.yellow[700],
iconTheme: IconThemeData(
color: Colors.yellow[700],
size: 28
),
accentIconTheme: IconThemeData(
color: Colors.yellow[700],
size: 32
),
primaryIconTheme: IconThemeData(
color: Colors.yellow[700],
size: 24
),
);
If you are on a primary area (places on a layout that uses the primary color) the accentIconTheme will be used
Otherwise the primaryIconTheme
The IconTheme I do not know for now, so anyone feels free to edit or put on a comment
The icon button was not picking the Icon Size defined in the Theme. Instead, I have to wrap the icon inside of the icon button in iconThemeData.
icon: IconTheme(
data: Theme.of(context).copyWith().iconTheme,
child: Icon(
Icons.search,
),
),
onPressed: () {},
),
This fixed the problem but it's not a good practice to wrap the Icon every time for the theme. There must be a proper solution for that.
make your raw a row of Icons (not IconButton).
then wrap your Icon with a widget that can be taped Like (InkWell or GestureDetector) to take advantage of the (onTap function) .
it’s not a good way actually but it will probably solve your problem .

How to set a text background with Flutter?

I'm very new to flutter but I'm interested in learning it pretty much from the beginning.
Right now I'm trying such a basic thing as changing the background color of some text, but I'm stuck.
import 'package:flutter/material.dart';
void main() {
final barColor = const Color(0xFFD63031);
var app = MaterialApp(
home: Scaffold(
backgroundColor: barColor,
),
);
Center(
child: Text('My Text',
textDirection: TextDirection.ltr,
),
);
runApp(app);
}
I do understand why the text doesn't show but I've been working on this for days now and I have tried a lot of different things without succeeding, so any help would be very appreciated.
Thank You
TL;DR - (Updated 07-08-2019)
Using style property (backgroundColor)
Text(
'Some text...',
style: TextStyle(backgroundColor: Colors.blue),
)
Using style property (background)
Text(
'Some text...',
style: TextStyle(background: Paint()..color = Colors.blue),
)
Using a DecoratedBox
const DecoratedBox(
decoration: const BoxDecoration(color: Colors.blue),
child: const Text('Some text...'),
);
Long answer
First of all, welcome to Flutter and StackOverflow :)
That happens because are misunderstand the way you should develop with Flutter.
As opposed to what happens with other architectures where you start in the main() function, instantiate your vars/objects and develop your flow from there, with Flutter you start your widget tree from your main() function as well, usually with a MaterialApp or CupertinoApp and fit in all its children to create your app.
So, as an example to get what you want, you must add your Center widget as the body of your Scaffold and then give a TextStyle to your Text widget, providing the property color. I gave it blue, but you can give it anything else you want. Thereby, this is your refactored code:
void main() => runApp(
MaterialApp(
home: Scaffold(
backgroundColor: const Color(0xFFD63031),
body: Center(
child: Text(
'MyText',
textDirection: TextDirection.ltr,
style: TextStyle(
background: Paint()..color = Colors.blue,
),
),
),
),
),
);
that will provide the following result
I suggest you take a look at the Awesome Flutter repo where you have a lot of good Flutter content to start with that can really help you out.
Simple you can set it in style property..
Text(
'My Text...',
style: TextStyle(backgroundColor: Colors.grey),
)
You can set this many properties to text in style: TextStyle()
{ bool inherit = true,
Color color,
Color backgroundColor,
double fontSize,
FontWeight fontWeight,
FontStyle fontStyle,
double letterSpacing,
double wordSpacing,
TextBaseline textBaseline,
double height,
Locale locale,
Paint foreground,
Paint background,
List<Shadow> shadows,
List<FontFeature> fontFeatures,
TextDecoration decoration,
Color decorationColor,
TextDecorationStyle decorationStyle,
double decorationThickness,
String debugLabel,
String fontFamily,
List<String> fontFamilyFallback,
String package
}