-1

I want to make my app responsive and to do so, I need to access to the width of the device directly in the material app so the Theme can adjust his size in function... When I try to do so, this error happens : MediaQuery.of() called with a context that does not contain a MediaQuery.

How to resolve that ?

Here is my code of my main class :


void main() {
  runApp(
      MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (_) => PlayerProvider()),
            ChangeNotifierProvider(create: (_) => QuestionsProvider()),
            ChangeNotifierProvider(create: (_) => SettingsProvider()),
            ChangeNotifierProvider(create: (_) => CategoryProvider()),
            ChangeNotifierProvider(create: (_) => FirebaseMessagingProvider()),
            ChangeNotifierProvider(create: (_) => TeamQuestionsProvider()),
            ChangeNotifierProvider(create: (_) => AppLanguageProvider()),
          ],
          child: BuvonsApp(),
      )
  );
}

// ignore: must_be_immutable
class BuvonsApp extends StatelessWidget {
  FirebaseAnalytics analytics = FirebaseAnalytics();
  BuildContext myContext;
  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    Provider.of<FirebaseMessagingProvider>(context, listen: false).init();
    Provider.of<SettingsProvider>(context, listen: false).initSharedPreferences();
    Provider.of<AppLanguageProvider>(context, listen: false).fetchLocale();
    return Consumer<AppLanguageProvider>(builder: (context, model, child) {
      return MaterialApp(
        debugShowCheckedModeBanner: false,
        navigatorObservers: [
          FirebaseAnalyticsObserver(analytics: analytics),
        ],
        title: 'Buvons',
        theme: ThemeData(
          brightness: Brightness.light,
          sliderTheme: SliderThemeData(
              valueIndicatorColor: Colors.orange,
              valueIndicatorTextStyle: GoogleFonts.rubik(fontSize: ResponsiveSize().responsiveSize(17, context), fontWeight: FontWeight.bold, color: Colors.white)
          ),
          textTheme: GoogleFonts.rubikTextTheme()
              .copyWith(bodyText2: GoogleFonts.rubik(fontSize: ResponsiveSize().responsiveSize(17, context), fontWeight: FontWeight.bold, color: Colors.white))
              .copyWith(subtitle1: GoogleFonts.rubik(fontSize: ResponsiveSize().responsiveSize(17, context), fontWeight: FontWeight.bold, color: Colors.grey[700]))
              .copyWith(subtitle2: GoogleFonts.rubik(fontSize: ResponsiveSize().responsiveSize(17, context), fontWeight: FontWeight.bold, color: Colors.grey[700]))
              .copyWith(headline5: GoogleFonts.rubik(fontSize: ResponsiveSize().responsiveSize(10, context), fontWeight: FontWeight.bold, color: Colors.white)),
          appBarTheme: AppBarTheme(
            centerTitle: true,
            iconTheme: IconThemeData(color: Colors.white),
            textTheme: GoogleFonts.rubikTextTheme()

                .copyWith(headline6: GoogleFonts.rubik(fontSize: ResponsiveSize().responsiveSize(25, context), fontWeight: FontWeight.bold, color: Colors.white)),
          ),
          tabBarTheme: TabBarTheme(
            labelColor: Colors.white,
            labelStyle: GoogleFonts.rubik(fontSize: ResponsiveSize().responsiveSize(15, context), fontWeight: FontWeight.bold),
            unselectedLabelColor: Colors.grey[100],
            unselectedLabelStyle: GoogleFonts.rubik(fontSize: ResponsiveSize().responsiveSize(13, context), fontWeight: FontWeight.bold),
          ),
          primarySwatch: Colors.orange,
          splashColor: Colors.orangeAccent,
          secondaryHeaderColor: Colors.orangeAccent,
          dividerColor: Colors.orange,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: SplashScreen(),
        navigatorKey: navigatorKey,
        locale: Provider.of<AppLanguageProvider>(context).appLocal,
        localizationsDelegates: [
          AppLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
        ],
        supportedLocales: [
          const Locale('en'),
          const Locale('fr'),
          const Locale('es'),
          // const Locale('de'),
          // const Locale('pl'),
        ],
      );
    },);
  }
}

Those ResponsiveSize().responsiveSize(15, context) are returning a double depending on the size of the device !

Here is the responsiveSize function :

double responsiveSize(double size, BuildContext context) {
    double shortestSideSize = MediaQuery.of(context).size.shortestSide;
    if (shortestSideSize < 450) {
      return size;
    } else if (shortestSideSize >= 450 && shortestSideSize < 850) {
      return size*1.5;
    } else {
      return size*2;
    }
  }
Simon B
  • 503
  • 12
  • 29

1 Answers1

2

I resolved the problem thanks to @Bruno Hugentobler Lipper

So I changed my function so I don't have to use the context and I put it in the same file as my main class.

Here is the function:

double _responsiveSize(double size) {
  double shortestSideSize = WidgetsBinding.instance.window.physicalSize.width/WidgetsBinding.instance.window.devicePixelRatio;
  if (shortestSideSize < 450) {
    return size;
  } else if (shortestSideSize >= 450 && shortestSideSize < 850) {
    return size*1.5;
  } else {
    return size*2;
  }
}
Simon B
  • 503
  • 12
  • 29