Set TextFromField style in Theme - flutter

So in my flutter app, I create TextFormField to use as an input like so (and return it in a scaffold):
final password = TextFormField(
controller: passController,
autofocus: false,
obscureText: true,
decoration: InputDecoration(hintText: 'Password'),
style: new TextStyle(color: Colors.orange),
);
I would like to change the style property inside a themeData, but I couldn't find which property to specify.
The closest one I could get to was textTheme: new TextTheme(body1: new TextStyle(color: Colors.orange)), but this one does nothing to my TextFormField.
How can I set the TextFormField style? Please help, I'm really new to Dart and also programming. I'm currently 13 and I have nobody to help me out with these types of things.
P.S: The complete code is on GitHub if needed: https://github.com/Legolaszstudio/novynotifier

Update:
If you want to change the Text within TextField by Theme of your Flutter App. It's now subtitle1 of TextTheme.
textTheme: TextTheme(
subtitle1: TextStyle(color: Colors.blue),
)

Uhm! That's a long question. TextFormField are subclass of the TextField. The default style of TextField could be found from source below.
final TextStyle style = themeData.textTheme.subhead.merge(widget.style);
So, you have 2 solutions for your source code.
Solution 1
Delete style property are inputted to password.
final password = TextFormField(
controller: passController,
autofocus: false,
obscureText: true,
decoration: InputDecoration(hintText: 'Password'),
style: new TextStyle(color: Colors.orange), // ★ => Delete this.
);
Define a custom subhead style from DataTheme and input into Material app.
MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
subhead: TextStyle(color: Colors.orange),
),
),
home: null,
)
Solution 2
Define a custom subhead style from DataTheme and input into Material app.
MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
subhead: TextStyle(color: Colors.orange),
),
),
home: null,
)
Copy this subhead style into password
final themes = Theme.of(context);
final password = TextFormField(
controller: passController,
autofocus: false,
obscureText: true,
decoration: InputDecoration(hintText: 'Password'),
style: themes.textTheme.subhead, // ★ => Update this.
);

I believe you are looking for subhead
textTheme: TextTheme(
subhead: TextStyle(color: Colors.orange),
)

2021 - 2022
The Material spec for typography changed significantly in 2021 and now uses display, headline, title, body, and label types. titleMedium is the one that will effect all of your TextFields and TextFormFields.
This fact is highlighted in the TextTheme class docs as well.
If you're using the the titleMedium TextStyle for something else, you can easily wrap your TextFields and TextFormFields in a Theme widget and update this style specifically for these widgets like this:
Theme(
data: Theme.of(context).copyWith(
textTheme: Theme.of(context).textTheme.copyWith(
titleMedium: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w300,
),
)),
child: TextField()
),

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)

how to disable the original text background color when selecting text in SelectableText.rich

Is there some way to disable the original text background color when selecting text in SelectableText.rich.
Otherwise the original background color(amber for example) is still there, which is different from the selected text background color (blue), and thus making it look like it is not selected.
Wrap it with theme and give it color i hope it helps
Theme(
data: ThemeData(textSelectionColor: Colors.green),
child: SelectableText.rich(
),
),
You need to set your select color first in ThemeData like this:
MaterialApp(
theme: ThemeData(
// use textSelectionTheme and set your needed color instead
textSelectionTheme: TextSelectionThemeData(
selectionColor: Colors.amber,
),
),
),
if need to use just this SelectableText.rich with specific color just wrap your SelectableText.rich with theme:
Theme(
data: ThemeData(
textSelectionTheme: const TextSelectionThemeData(
selectionColor: Colors.amber,
// selectionColor: Colors.transparent, // it can make select color transparent that you need or make that backgroundColor: Color.transparent
),
),
child: const SelectableText.rich(
TextSpan(
children: [
TextSpan(
text: 'test ',
style:
TextStyle(color: Colors.black, backgroundColor: Colors.amber
// this backgroundColor make the white backcolor into amber
),
),
],
),
toolbarOptions: ToolbarOptions(cut: true), // tools like copy, paste
enableInteractiveSelection: false, // you can enable select color
cursorColor: Colors.red, // this is an option if you want change
),
),

Flutter change Textfield selected background color

I have a TextField which looks like this at the moment:
As you can see the selected color is purple. But how can I change that color for that specific TextField ? I do not want to change the AppThemeData. I couldn't find anything on this ... Happy for every help!
you can try and wrap it with Theme and use SplashColor to be something like this :
Theme(
data: ThemeData(textSelectionColor: Colors.green),
child: TextField(
autofocus: false,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: 'Mail',
),
),
);
or do this in main :
theme: ThemeData(
accentColor: Color(0xffBA379B).withOpacity(.6),
primaryColor: Color(0xffBA379B),
textSelectionTheme: TextSelectionThemeData(
selectionColor: Color(0xffBA379B).withOpacity(.5),
cursorColor: Color(0xffBA379B).withOpacity(.6),
selectionHandleColor: Color(0xffBA379B).withOpacity(1),
),
```

Change the Highlight Color of selected text

When the user select a text from inside a TextField, the default highlight color is blue. How to change it to green for example ?
2021 answer
Wrap with Theme and use copyWith to preserve other theme data.
Theme(data: Theme.of(context).copyWith(
textSelectionTheme: TextSelectionThemeData(
selectionColor: Colors.green)),
child: TextFormField()
)
Wrap your text widget with theme and assign the color to the textSelectionColor property inside ThemeData
refer below code for same:- I have changed the text selection color to green
Theme(
data: ThemeData(textSelectionColor: Colors.green),
child: TextField(
controller: _inputController,
decoration: InputDecoration(hintText: "Input"),
),
),
change the value of textSelectionColor of your ThemeData and it will give you the result you are looking for.
please use this code.
Widget build(BuildContex contex){
return MaterialApp{
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.green,
iconTheme: IconThemeData(
color: kGreenColor,
),
hoverColor: kPrimaryColor,
indicatorColor: kPrimaryColor,
),
}
}

Cleanly overriding parts of a theme locally in Flutter

I have a widget which has two TextFields as descendants. I would like to apply the same styling to these TextFields. My understanding is that the right way to do this is to apply a localized theme to my widget tree. The following is my attempt. This is a code snippet from my root widget's build function. Is there not a cleaner way to do this?
final ThemeData _themeData = Theme.of(context);
return Theme( // HACK
data: _themeData.copyWith(
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(),
),
textTheme: _themeData.textTheme.copyWith(
subhead: _themeData.textTheme.subhead.copyWith(
fontSize: 30.0,
),
),
),
child: _buildTheRestOfMyWidgetTree(context),
);
The thing that I am annoyed by is that to override a single property (_themeData.textTheme.subhead.fontSize), I have to explicitly and manually make copies of three intermediate data structures (_themeData, then _themeData.textTheme, then _themeData.textTheme.subhead).
While I can understand the frustration of having to "copy" everything, this is how you should do it.
Data are immutable in Flutter. You cannot mutate them, you are forced to clone them with different properties.
Therefore your assumption is correct: If you want to modify a nested property, you have to clone all of its parents too. Which leads to:
final ThemeData theme = Theme.of(context);
theme.copyWith(
textTheme: theme.textTheme.copyWith(
subhead: theme.textTheme.subhead.copyWith(
fontSize: 30.0,
),
),
);
Again: you cannot avoid it.
It would help if you packaged that part of the code up and made it a widget so that your tree is cleaner. That's how it's done in this example.
class TextFieldOverride extends StatelessWidget {
const TextFieldOverride({this.child});
final Widget child;
#override
Widget build(BuildContext context) {
final themeData = Theme.of(context);
return Theme(
child: child,
data: themeData.copyWith(
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder()),
textTheme: themeData.textTheme.copyWith(
subhead: themeData.textTheme.subhead.copyWith(
fontSize: 30.0))));
}
}
...
TextFieldOverride(
child: TextField(...)
)
Or if there are few places the code will be duplicated, you can just make the changes directly:
...
child: TextField(
style: Theme.of(context).textTheme.subhead.copyWith(fontSize: 30.0),
decoration: InputDecoration(border: OutlineInputBorder(),
...
)
)
Or perhaps the best choice is to create a function that does the above for you.
TextField buildTextField(BuildContext context) => TextField(
style: Theme.of(context).textTheme.subhead.copyWith(fontSize: 30.0),
decoration: InputDecoration(border: OutlineInputBorder(),
...
)
)