Screen util is used to set the widget size to match the UI design. UI design should have a base device and follows the constraint. Base device width and height should be set as defaultWidth
and defaultHeight
or defined on init.
import 'dart:math'; import 'package:flutter/material.dart'; class ScreenUtil { static final ScreenUtil _instance = ScreenUtil._(); static const int defaultWidth = 375; static const int defaultHeight = 667; /// Size of the phone in UI Design , px late final num uiWidthPx; late final num uiHeightPx; late final BuildContext rootContext; /// allowFontScaling Specifies whether fonts should scale /// to respect Text Size accessibility settings. The default is false. late bool allowFontScaling; static late MediaQueryData _mediaQueryData; factory ScreenUtil() { return _instance; } ScreenUtil._(); /// /// This should be called once at app init /// * `width` the UI design width /// * `height` the UI design height /// static void init( BuildContext context, { num width = defaultWidth, num height = defaultHeight, bool allowFontScaling = false, }) { _instance; _instance.uiWidthPx = width; _instance.uiHeightPx = height; _instance.allowFontScaling = allowFontScaling; _instance.rootContext = context; _mediaQueryData = MediaQuery.of(context); } /// The number of font pixels for each logical pixel. static double get textScaleFactor => _mediaQueryData.textScaleFactor; /// The size of the media in logical pixels (e.g, the size of the screen). static double get pixelRatio => _mediaQueryData.devicePixelRatio; /// The horizontal extent of this size. static double get screenWidthDp => _mediaQueryData.size.width; ///The vertical extent of this size. dp static double get screenHeightDp => _mediaQueryData.size.height; /// The vertical extent of this size. px static double get screenWidth => screenHeightDp * pixelRatio; /// The vertical extent of this size. px static double get screenHeight => screenHeightDp * pixelRatio; /// The offset from the top static double get statusBarHeight => _mediaQueryData.padding.top; /// The offset from the bottom. static double get bottomBarHeight => _mediaQueryData.padding.bottom; /// The ratio of the actual dp to the design draft px double get scaleWidth => screenWidthDp / uiWidthPx; double get scaleHeight => (screenHeightDp - statusBarHeight - bottomBarHeight) / uiHeightPx; double get scaleText => scaleWidth; double get minimumScale => min(scaleWidth, scaleHeight); /// Adapted to the device width of the UI Design. /// Height can also be adapted according to this to ensure no deformation , /// if you want a square num setWidth(num width) => width * scaleWidth; /// Highly adaptable to the device according to UI Design /// It is recommended to use this method to /// achieve a high degree of adaptation /// when it is found that one screen in the UI design /// does not match the current style effect, /// or if there is a difference in shape. num setHeight(num height) => height * scaleHeight; ///Font size adaptation method num setSp(num fontSize, {bool allowFontScalingSelf = false}) => (allowFontScaling || allowFontScalingSelf) ? (fontSize * scaleText) : (fontSize * scaleText) / textScaleFactor; num setMinSp(num fontSize) => fontSize * minimumScale; } extension ScreenUtilExt on num { num get h => ScreenUtil().setHeight(this); num get w => ScreenUtil().setWidth(this); num get sp => ScreenUtil().setSp(this); }
To use the screen utils, we need to call ScreenUtil.init
in app.dart at MaterialApp
builder.
MaterialApp( builder: (context, widget) { ScreenUtil.init(context); return MyScreen(); }, ... )
Once it is initiated, we can use ScreenUtil().setHeight(num)
, ScreenUtil().setWidth(num)
, ScreenUtil().setSp(num)
. Or we can use the extension by importing the ScreenUtils, example:
import 'package:generic_ui/utils/screen_utils.dart' ..... Widget build(BuildContext context) { return SizedBox( height: 100.h, width: 50.w, ) }