Cant use MediaQuery.of(context) for Themes in Flutter - flutter

Hi I am trying to create several TextTheme and change the fonts sizes using MediaQuery.of(context) based on this article:
Flutter — Effectively scale UI according to different screen sizes
But I am getting this error:
MediaQuery.of() called with a context that does not contain a MediaQuery.
I know based on this post: Flutter Error: MediaQuery.of() called with a context that does not contain a MediaQuery
I should use MediaQuery on my HomePage but then I cannot create themes using MediaQuery then?
Here is my code:
child:
MaterialApp(
theme: ThemeData(
/// TextFields Handlers transparent
textSelectionHandleColor: Colors.transparent,
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: ZoomPageTransitionsBuilder(),
},
),
textTheme: TextTheme(
/// Pages Titles
headline1: textTheme(
fontSize: (MediaQuery.of(context).size.width / 100) * 1.5,
fontWeight: FontWeight.w600,
color: Globals.allColors['celeste'],
),
headline2: textTheme(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Globals.allColors['cetaceanBlue']),
...
The error is at:
(MediaQuery.of(context).size.width / 100) * 1.5,
Thanks in advance!

No, you cannot create your material theme with values retrieved from Mediaquery. You set 'default' font size, etc. in your material app theme data. Then in your home page build method you call Mediaquery and modify your font size for that page if necessary.

Try wrapping your entire homepage in a builder widget.

You could do this like a one-off kind of thing. You could save your text themes in a themes.dart file or something like that..and then subsequently, you could have a loading page, where you make a MediaQuery and calculate your theme values there.
I think you might have to run setState after that, maybe not, because when you navigate to your home screen from there, the values of the theme would have updated.

MediaQuery needs the MaterialApp widget as an ancestor, you can't use it when constructing the MaterialApp itself. A workaround is not using the theme property but wrapping the descendants with a Theme widget using the builder property. It will have the MaterialApp as an ancestor so you can use MediaQuery there.
MaterialApp(
builder: (context, child) {
return Theme(
data: ThemeData(
// your theme
// can use e.g. MediaQuery.of(context).size.width here
),
child: child,
);
},
home: SomeScreen(),
// etc, no theme here
)

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

Primary custom color not working in flutter

I have a problem here I want to change color of textbutton from themedata but its not working. Here is my code :
darkTheme: ThemeData(
primaryColor:Colors.white,
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(primary: Colors.white),
)
),
and my button code :
TextButton(
style: TextButton.styleFrom(
primary: Theme.of(context).primaryColor,
textStyle: TextStyle(fontSize: 16),),
onPressed: (){}, child: Text("Hellosir",))
I can think of two problems why this is not working.
First, you want to access ThemeData defined in darkTheme, but your themeMode is not dark. So in MaterialApp add themeMode: ThemeMode.dark parameter as well.
Second, your button where you call Theme.of(context).primaryColor is inside same widget as your definition of Theme, and your context still doesn't have that data. So only context of children of current widget have this data. Solution would be to make a new widget with your button inside it, or wrap your button with Builder widget which have context inside its builder.
Your problem can be first, second or both.

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

Change highlight colour for textfield in flutter

Is there any way to change the colour of a Textfield's highlight in Flutter?
So when I highlight it does not look like this:
Thank you!
Solution 1. You can change the textSelectionColor in the theme of your app:
theme: ThemeData.dark().copyWith(
textSelectionColor: Colors.black
),
Solution 2. You can change the textSelectionColor only for a specific TextField by wrapping it with a Theme widget:
Theme(
data: ThemeData(
textSelectionColor: Colors.black,
),
child: TextField(
),
),

How to change color of the bubble (under cursor) on EditText in Flutter

How can I change the color of the bubble that appears upon text selection in a Text or TextFormField or .. in Flutter?
Here is the same question but for native code.
According to this flutter documentation, textSelectionHandleColor is deprecated. You should use selectionHandleColor instead inside TextSelectionThemeData widget like the code below.
theme: ThemeData(
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.red,
selectionColor: Colors.green,
selectionHandleColor: Colors.black,
),
)
You may use the textSelectionHandleColor property.
Theme(
data: Theme.of(context).copyWith(
textSelectionHandleColor: Colors.green,
),
child: TextField(),
);
In case of iOS TextField, i've found no other solution than adding the snippet below to the top level MaterialApp like this:
MaterialApp => theme: ThemeData( snippet )
snippet:
cupertinoOverrideTheme: CupertinoThemeData( primaryColor: Color(0xff554270), ),
i couldn't apply this snippet by wrapping the TextField with Theme(data: Theme.of(context).copyWith( ... did not work.. dunno why ]: (maybe this one would be my fault in somewhere but adding it to the app lv definitely worked tho)
Hope this answer help future iOS wanderers [: