Change size of text according to screen width in Flutter - flutter

I want the text size to remain the same however i want it to be bigger when on a larger screen width device.
MediaQueryData queryData;
#override
Widget build(BuildContext context) {
queryData = MediaQuery.of(context);
Text("Hello.",
style: TextStyle(
fontSize: queryData.size.width, color: Colors.white),
),
}
However, it became so big when i tried queryData.size.width. in this case i want the text to expand according to different devices screens.

You just need to multiply the result from the media query by a constant.
double width = MediaQuery.of(context).size.width;
return Text(
"Hello.",
style: TextStyle(
fontSize: width * 0.2,
color: Colors.white,
),
);

Define a class named sizeconfig:
class SizeConfig {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double blockSizeHorizontal;
static double blockSizeVertical;
static double _safeAreaHorizontal;
static double _safeAreaVertical;
static double safeBlockHorizontal;
static double safeBlockVertical;
void init(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData.size.width;
screenHeight = _mediaQueryData.size.height;
blockSizeHorizontal = screenWidth / 100;
blockSizeVertical = screenHeight / 100;
_safeAreaHorizontal =
_mediaQueryData.padding.left + _mediaQueryData.padding.right;
_safeAreaVertical =
_mediaQueryData.padding.top + _mediaQueryData.padding.bottom;
safeBlockHorizontal = (screenWidth - _safeAreaHorizontal) / 100;
safeBlockVertical = (screenHeight - _safeAreaVertical) / 100;
}
}
And in your page initialize this class using SizeConfig().init(context)
then on your fontsize :SizeConfig.screenWidth * .02.

Your question is relevant also for Containers, Buttons, etc... So I suggest you to check how this amazing open source (using the alibaba redux) solved this issue using an utility-adapter file in several places like in the account header page.
Another excellent option is to check the flutter-screen-util dependency, they have a good example there.

You can use flutter_screenutil to set font size responsive to any screen layout also with this package you can make your other widgets responsive by its setWidth() and setHeight() methods,
You can check its documentation here : flutter_screenutil

We can use view vw and vh unit to provide font-size, which will make your text more visible with different viewport size.
h1 {
font-size: 5.9vw;
}
h2 {
font-size: 3.0vh;
}
p {
font-size: 2vmin;
}
1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, whichever is smaller
1vmax = 1vw or 1vh, whichever is larger

Related

Center an incrementing number using the "setByPostion" component in Flutter

I am developing a new game and ran into an issue where when my score increases to more than 10 or by another decimal it will not center properly due to only the first decimal in the number being in the center of the screen.
import 'package:flame/components/text_component.dart';
import 'package:flame/game.dart';
import 'package:flame/position.dart';
import 'package:flame/text_config.dart';
import 'package:flutter/material.dart';
class Test extends BaseGame{
TextComponent _scoreText;
int score;
TextComponent _text;
Test() {
// SCORE TEXT
score = 0;
_scoreText = TextComponent(score.toString(),
config: TextConfig(
color: Colors.white, fontFamily: 'Audiowide', fontSize: 70));
add(_scoreText);
}
void resize(Size size) {
super.resize(size);
_scoreText.setByPosition(Position(
(size.width / 2) - (_scoreText.width / 2), (size.height / 10)));
}
}
I fixed this problem by using the anchor widget, making its origin the center of the text box and not the top left.
void resize(Size size) {
super.resize(size);
_scoreText.setByPosition(Position(
_scoreText.anchor = Anchor.center;
(size.width / 2), (size.height / 10)));
}

Real height in flutter?

I am trying to retrieve the real height in Flutter. I tried different options:
MediaQuery.of(context).size.height * MediaQuery.of(context).devicePixelRatio
or
WidgetsBinding.instance.window.physicalSize.height
I add these 2 lines in a new Flutter app (from scratch, just the new counter app screen that flutter creates)
I also tried to use a global key, and it does not work (meaning by that that I get the same result). I am testing it in a Samsung a10, which, according to wikipedia, has a 720 x 1520 pixels. The width I have no problem in calculating it, but the height, is always giving me 1424.0. Why I am not getting the full height? Is happening me with more phone models.
Please see the documentation for the physicalSize property:
This value does not take into account any on-screen keyboards or other system UI. The padding and viewInsets properties provide information about how much of each side of the view may be obscured by system UI.
try to use this utility class it gives me the right result
class ScreenUtil {
static ScreenUtil instance = new ScreenUtil();
int width;
int height;
bool allowFontScaling;
static MediaQueryData _mediaQueryData;
static double _screenWidth;
static double _screenHeight;
static double _screenHeightNoPadding;
static double _pixelRatio;
static double _statusBarHeight;
static double _bottomBarHeight;
static double _textScaleFactor;
static Orientation _orientation;
ScreenUtil({
this.width = 1080,
this.height = 1920,
this.allowFontScaling = false,
});
static ScreenUtil getInstance() {
return instance;
}
void init(BuildContext context) {
MediaQueryData mediaQuery = MediaQuery.of(context);
_mediaQueryData = mediaQuery;
_pixelRatio = mediaQuery.devicePixelRatio;
_screenWidth = mediaQuery.size.width;
_screenHeight = mediaQuery.size.height;
_statusBarHeight = mediaQuery.padding.top;
_bottomBarHeight = mediaQuery.padding.bottom;
_textScaleFactor = mediaQuery.textScaleFactor;
_orientation = mediaQuery.orientation;
_screenHeightNoPadding =
mediaQuery.size.height - _statusBarHeight - _bottomBarHeight;
}
static MediaQueryData get mediaQueryData => _mediaQueryData;
static double get textScaleFactory => _textScaleFactor;
static double get pixelRatio => _pixelRatio;
static Orientation get orientation => _orientation;
static double get screenWidth => _screenWidth;
static double get screenHeight => _screenHeight;
static double get screenWidthPx => _screenWidth * _pixelRatio;
static double get screenHeightPx => _screenHeight * _pixelRatio;
static double get screenHeightNoPadding => _screenHeightNoPadding;
static double get statusBarHeight => _statusBarHeight * _pixelRatio;
static double get bottomBarHeight => _bottomBarHeight * _pixelRatio;
get scaleWidth => _screenWidth / instance.width;
get scaleHeight => _screenHeight / instance.height;
setWidth(int width) => width * scaleWidth;
setHeight(int height) => height * scaleHeight;
setSp(int fontSize) => allowFontScaling
? setWidth(fontSize)
: setWidth(fontSize) / _textScaleFactor;
}
in your build method first call
ScreenUtil().init(context);
then you can call ScreenUtil.screenHeight

The operator '*' can't be unconditionally invoked because the receiver can be 'null'. Try adding a null check to the target ('!')

I used this code for responsiveness in my UI. So what this code basically does is calculate the size of the screen and I use the functions below to put the exact font size according to the design provided to me in Figma or Adobe XD. Using this method, I was able to create pixel-perfect UI.
After upgrading to Flutter 2.0.3, I am getting null safety errors. I was able to solve most of them but I am not able to solve this error.
Please advice.
Complete Code
import 'package:flutter/material.dart';
class SizeConfig {
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;
if (orientation == Orientation.landscape) {
defaultSize = screenHeight! * 0.024;
} else {
defaultSize = screenWidth! * 0.024;
}
}
}
double getSize(double size) {
var defaultsSize = SizeConfig.defaultSize * size;
return (defaultsSize / 10);
}
// Get the proportionate height as per screen size
double getProportionateScreenHeight(double inputHeight) {
double screenHeight = SizeConfig.screenHeight!;
// 812 is the layout height that designer use
return (inputHeight / 812.0) * screenHeight;
}
// Get the proportionate width as per screen size
double getProportionateScreenWidth(double inputWidth) {
double screenWidth = SizeConfig.screenWidth!;
// 375 is the layout width that Figma provides
return (inputWidth / 375.0) * screenWidth;
}
Error
Because SizeConfig.defaultSize is nullable, you need to make sure that its value should not be null.
You can add some assertion to notify the caller that SizeConfig should be initialized first. Then, you can change it to SizeConfig.defaultSize!.
Sample...
double getSize(double size) {
assert(
SizeConfig.defaultSize != null,
"SizeConfig should be initialized (only once) before calling getSize(...). Refer to SizeConfig.init(...).",
);
var defaultsSize = SizeConfig.defaultSize! * size;
return (defaultsSize / 10);
}
Problem:
You get this error because the object you're invoking * on can be null.
Example:
int? count = 1;
void main() {
print(count * 2); // error: The operator '*' can't be unconditionally invoked ...
}
Solutions:
Use a local variable:
int? count = 1;
void main() {
var i = count;
if (i != null) {
print(i * 2); // Prints 2
}
}
Use bang operator (!)
int? count = 1;
void main() {
print(count! * 2); // Prints 2
}
You have three options:
Use the bang operator:
int? count = 1;
void main() {
// will throw an error if count is null
print(count! * 2);
}
Use the ?? operator:
int? count = 1;
void main() {
// safe
print((count ?? 1) * 2);
}
Use an if - else statement:
int? count = 1;
void main() {
if(count != null) {
print(count! * 2);
} else {
print('count is null');
}
}

flutter specifying width, height, paddings, margins etc in percentages?

Is there a way in flutter which allows the widths, heights, paddings, margins etc being specified in percentages of screen dimensions instead of writing calculations in every widget?
Passing around a provider or extending some base class for this trivial thing is not feeling right.
The only known solution is to use MediaQuery. I implemented a helper class that I just call the methods for:
class SizeManager {
var _context;
double _screenHeight;
double _screenWidth;
SizeManager(this._context) {
_screenHeight = MediaQuery.of(_context).size.height;
_screenWidth = MediaQuery.of(_context).size.width;
}
double scaledHeight(double value) {
return value * _screenHeight / 100;
}
double scaledWidth(double value) {
return value * _screenWidth / 100;
}
}
In every build(), just before the return, call it like:
SizeManager sizeManager = new SizeManager(context);
And whenever you want to set margins/padding/size:
Container(
padding: EdgeInsets.symmetric(vertical: sizeManager.scaledHeight(2.5)), //Gives a 2.5 % height padding
),

NonHierarchicalViewBasedAlgorithm from android-maps-utils use pixel or dp on constructor params?

The class NonHierarchicalViewBasedAlgorithm from googlemaps/android-maps-utils have a constructor:
public NonHierarchicalViewBasedAlgorithm(int screenWidth, int screenHeight) {
mViewWidth = screenWidth;
mViewHeight = screenHeight;
}
But Im not sure if I should send the width in pixels or in dp.
Any ideas?
Pretty sure all of the Google android map parts work in raw pixels, not dip.
From the source code of NonHierarchicalViewBasedAlgorithm class (https://github.com/googlemaps/android-maps-utils/blob/main/library/src/main/java/com/google/maps/android/clustering/algo/NonHierarchicalViewBasedAlgorithm.java):
/**
* #param screenWidth map width in dp
* #param screenHeight map height in dp
*/
public NonHierarchicalViewBasedAlgorithm(int screenWidth, int screenHeight) {
mViewWidth = screenWidth;
mViewHeight = screenHeight;
}