2

started to learn Flutter so I'm thinking if is it possible to create a function that returns a ThemeData object, but inside this function I wanna use MediaQuery.of(context). I mean, I know I can create such a function, but if I use MediaQuery.of(context) inside of it, I have an error (MediaQuery.of() called with a context that does not contain a MediaQuery) complaining about the missing of MediaQueryProvider. I know I can use MediaQuery in child elements of MaterialApp, but I have a design problem now. Imagine this:

ThemeData getTheme(BuildContext context) {
  // I wanna be able to call MediaQuery.of(contex) here
  return ThemeData();
}

MaterialApp(
   home: home,
   // the getTheme() must be able to use MediaQuery. It takes a context and returns a ThemeData object
   theme: theme.getTheme(context),
   routes: routes,
)

Is there a way to do it? or event better, Should I do it?

Thank you for your help.

  • Does this answer your question? [Flutter Error: MediaQuery.of() called with a context that does not contain a MediaQuery](https://stackoverflow.com/questions/50214338/flutter-error-mediaquery-of-called-with-a-context-that-does-not-contain-a-med) – Amon C Sep 02 '20 at 19:04
  • well, i'm think not, the link helped me to understand the problem, but it does not help to find a solution – Jesley Cáceres Marcelino Sep 02 '20 at 20:47
  • Ok. I will have a deeper look later. – Amon C Sep 02 '20 at 21:02

3 Answers3

1

A workaround is not using the theme property of MaterialApp 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: getTheme(context), // you can use MediaQuery.of(context) in the called function
      child: child,
    );
  },
  home: HomeScreen(),
  // etc, no theme here
)
0

Welcome to the brotherhood. Actually, to call for MediaQuery you will need to wrap your main widget with a MaterialApp() which usually is done in your main.dart file. Here is an example:

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

Hope it helped!

0

You can try this.

Create a stateless/ stateful widget for the home of your MaterialApp, and inside that, create your getTheme method.

Example,

homePage extends StatelessWidget{

ThemeData getTheme(BuildContext context) {
  // Call MediaQuery.of(contex) here
  return ThemeData();
}

@override
//build method

}//homePage ends here.

Now, in your material app, simple call that method.

MaterialApp(
   home: homePage(),
  
   theme: homePage().getTheme(context),
   routes: routes,
)
Madhavam Shahi
  • 1,166
  • 6
  • 17
  • 1
    First I would like to thanks you, but sorry it didn't work for me. I am able to make it works using something like this: 1) listen to a build event of a child using a function that takes a child context, so in this function I call setState to assign a class filed a new theme that is passed to MaterialApp. It works, but I really don`t like this Design – Jesley Cáceres Marcelino Sep 02 '20 at 21:11