0

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

    );
  }
}

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @usamamajid. I will give it a try.
Maybe you can answer with more specific code @usamamajid. I have tried for a few hours and cannot figure out how to resolve the issue with your suggestion. The Dimensions data resides in a class in the app and not on the database so I have no idea how to 'load' the data to initState. I tried everything I could think of and searched on SO but can't figure it out. A more specific answer would be helpful if possible. I appreciate the help regardless. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.