Carleton Y
Carleton Y

Reputation: 309

How to access variable values before Flutter app first loads

I'm trying to include dynamic values for widget sizes in my app so that font sizes, container sizes, etc adjust in size based on the user's screen size.  I use Provider for State Management and I just added GetX to create the class of dynamic variables (Dimensions) that will hold the various size variables used in the app.  Getting everything to work when the dynamic values are added directly to widgets hasn't been a problem.  The problem that I am having is related to including dynamic values inside of my Theme class or other classes that provide data down the widget tree using Provider.  There are no issues with Provider, only with how I have written my code.  My best guess is that my Theme class is initially loaded with null values for the Dimension class variables since I have my MultiProvider above the (Get) Material App widget.  But as a beginner that is purely a guess and not based on experience or coding knowledge. 

The error message is: type 'Null' is not a subtype of double in type cast.

The error points to the variables in my Dimensions class.  Is this just a bad approach or is there a way to provide the app with access to the Dimensions class as soon as it is launched?  I have included some of of the code from my Theme class as an example of how I am trying to use it along with other code.  Thanks in advance for any help.

class MyApp extends StatelessWidget {
  const MyApp({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<MenuInfoProvider>(
          create: (context) => MenuInfoProvider(
            MenuName.homePage,
            menuIcon: Icons.home,
            menuText: MenuLabelString.home,
          ),
        ),
        ChangeNotifierProvider<ThemeProvider>(
          create: (context) => ThemeProvider(),
        ),
        ChangeNotifierProvider<AccountSettingsPageProvider>(
          create: (context) => AccountSettingsPageProvider(),
        ),
        ChangeNotifierProvider<UserProvider>(
            create: (context) => UserProvider()),
        Provider<Database>(
          create: (context) => FirestoreDatabase(
            uid: Auth().currentUser!.uid,
          ),
        ),
        Provider<AuthBase>(
          create: (context) => Auth(),
        ),
      ],
      builder: (context, _) {
        final themeProvider = Provider.of<ThemeProvider>(context);

        return GetMaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Test App Title',
          theme: ThemeProvider.lightTheme,
          darkTheme: ThemeProvider.darkTheme,
          themeMode: themeProvider.currentTheme,
          initialRoute: RouteStrings.landing,
          onGenerateRoute: RouteGenerator.generateRoute,
        );
      },
    );
  }
}

class Dimensions {

  static double screenHeight = Get.context?.height as double;
  static double screenWidth = Get.context?.width as double;
  
  static double height10 = screenHeight / 68.35;
  static double height15 = screenHeight / 45.57;
  static double height20 = screenHeight / 34.18;
  
  static double fontSize20 = screenHeight / 34.18;
  static double fontSize16 = screenHeight / 42.72;
  static double fontSize14 = screenHeight / 48.22;
  static double fontSize12 = screenHeight / 56.96;
  static double fontSize10 = screenHeight / 68.35;
}

class ThemeProvider extends ChangeNotifier {
  ThemeMode currentTheme = ThemeMode.system;

  bool get isDarkMode => currentTheme == ThemeMode.dark;

  void toggleTheme({required bool isOn}) {
    currentTheme = isOn ? ThemeMode.dark : ThemeMode.light;
    notifyListeners();
  }

  static ThemeData get lightTheme {
    return ThemeData(
      
      primaryTextTheme: TextTheme(
        subtitle1: TextStyle(
          color: AppColors.accentTextBlue800,
          decoration: TextDecoration.underline,
          fontFamily: AppTextStyle.robotoFont,
          fontSize: Dimensions.fontSize16,
          fontWeight: FontWeight.w400,
          letterSpacing: 0.15,
        ),
      ),

    );
  }
}

Upvotes: 0

Views: 638

Answers (1)

Usama majid
Usama majid

Reputation: 202

Get the data in initState and check if the data has completely loaded yet. If the data is not completely loaded user CupertinoActivityIndicator() and after the data has loaded just setState. I hope this will work.

Upvotes: 1

Related Questions