To create responsive apps in Flutter, I use size_configs.dart
file which handles the responsiveness of the code in different screens. I inject the SizeConfigs().init(context);
below the MyApp
root widget to make the app responsive. The init method takes in a context to scale the width, height and fontSize. I created functions as well so that I can put the exact values of fonts which I get from Figma designs instead of percentage like in the Sizer package.
The getFont(), getHeight(), getWidth() function take in a double and create responsive size for the text according to the screen.
size_configs.dart
import 'package:flutter/material.dart';
class SizeConfigs {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double defaultSize;
static Orientation orientation;
void init(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData.size.width;
screenHeight = _mediaQueryData.size.height;
orientation = _mediaQueryData.orientation;
// On iPhone 11 the defaultSize = 10 almost
// So if the screen size increase or decrease then our defaultSize also vary
defaultSize = orientation == Orientation.landscape
? screenHeight * 0.024
: screenWidth * 0.024;
}
}
double getFont(double size) {
double defaultsSize = SizeConfigs.defaultSize * size;
return (defaultsSize / 10);
}
// Get the proportionate height as per screen size
double getHeight(double inputHeight) {
double screenHeight = SizeConfigs.screenHeight;
// 812 is the layout height that designer use
return (inputHeight / 812.0) * screenHeight;
}
// Get the proportionate width as per screen size
double getWidth(double inputWidth) {
double screenWidth = SizeConfigs.screenWidth;
// 375 is the layout width that Figma provides
return (inputWidth / 375.0) * screenWidth;
}
I also have an app_theme.dart
file where I store the ThemeData that I use in my app.
app_theme.dart
class AppTheme {
//Light Theme Colors
static Color lightBackgroundColor = const Color(0xffFFFFFF);
static Color lightPrimaryColor = const Color(0xffF5E8EA);
static Color lightSecondaryColor = const Color(0xff192533);
static Color iconColor = const Color(0xffEEF0EB);
///Light Theme configuration
static final lightTheme = ThemeData(
textTheme: lightTextTheme,
brightness: Brightness.light,
backgroundColor: lightBackgroundColor,
primaryColorLight: lightPrimaryColor,
accentColor: lightSecondaryColor,
selectedRowColor: tertiaryColor,
unselectedWidgetColor: iconColor,
toggleButtonsTheme:
ToggleButtonsThemeData(color: tertiaryColor, disabledColor: iconColor),
//buttonTheme: ButtonThemeData(buttonColor: tertiaryColor),
toggleableActiveColor: tertiaryColor,
visualDensity: VisualDensity.adaptivePlatformDensity,
);
///Light TextTheme configuration
static final TextTheme lightTextTheme = TextTheme(
headline4: _mainTitle,
headline5: _title,
subtitle1: _subtitle,
bodyText1: _body,
bodyText2: _detail,
);
/// Main Title
static final TextStyle _mainTitle = TextStyle(
fontFamily: "RedHatDisplay-Black",
fontSize: 36,
);
/// Title
static final TextStyle _title = TextStyle(
fontFamily: "RedHatDisplay-Bold",
fontSize: 28,
);
/// Subtitle
static final TextStyle _subtitle = TextStyle(
fontFamily: "RedHatDisplay-Medium",
fontSize: 18,
);
/// Body
static final TextStyle _body = TextStyle(
fontFamily: "RedHatDisplay-Regular",
fontSize: 16,
);
/// Detail
static final TextStyle _detail = TextStyle(
fontFamily: "RedHatDisplay-Regular",
fontSize: 14,
);
}
The problem lies here. ThemeData doesn't have a BuildContext, so MediaQuery doesn't work in it, thus I can't call my getFont()
function inside the fontSize
parameter of the TextStyle
.
What I do is use the copyWith
method and override the fontSize property with the function.
Text(
'HomeScreen',
style: Theme.of(context).textTheme.headline4.copyWith(fontSize: getFont(18)),
),
I want to just use the Theme.of(context).headline4
wherever I need them and its font should act as responsively and TextStyle should be able to take my getFont()
function.
static final TextStyle _mainTitle = TextStyle(
fontFamily: "RedHatDisplay-Black",
//This should take in the getFont function from the SizeConfigs.
fontSize: getFont(36),
);
TL;DR - I want a way to pass MediQuery data(SizeConfigs) which works with BuildContext to ThemeData which does not have a BuildContext.
Some of the properties require context to obtain their values.
To use such properties globally (without providing context),
Once you set these parameters globally, you don't need to pass context at any point.
User contributions licensed under CC BY-SA 3.0