import 'dart:ui'; import 'package:flutter/material.dart'; import 'dart:ui' as ui show window; ///默认设计稿尺寸(单位 dp or pt) double _designW = 360.0; double _designH = 640.0; double _designD = 3.0; /** * 配置设计稿尺寸(单位 dp or pt) * w 宽 * h 高 * density 像素密度 */ /// 配置设计稿尺寸 屏幕 宽,高,密度。 /// Configuration design draft size screen width, height, density. void setDesignWHD(double? w, double? h, {double? density = 3.0}) { _designW = w ?? _designW; _designH = h ?? _designH; _designD = density ?? _designD; } /// Screen Util. class ScreenUtil { double _screenWidth = 0.0; double _screenHeight = 0.0; double _screenDensity = 0.0; double _statusBarHeight = 0.0; double _bottomBarHeight = 0.0; double _appBarHeight = 0.0; MediaQueryData? _mediaQueryData; static final ScreenUtil _singleton = ScreenUtil(); static ScreenUtil getInstance() { _singleton._init(); return _singleton; } _init() { //先用老的方法获取,如果获取不到再使用新方法获取 MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window); if (_mediaQueryData != mediaQuery) { _mediaQueryData = mediaQuery; _screenWidth = mediaQuery.size.width == 0.0 ? MediaQueryData.fromView(PlatformDispatcher.instance.views.first).size.width : mediaQuery.size.width; _screenHeight = mediaQuery.size.height == 0.0 ? MediaQueryData.fromView(PlatformDispatcher.instance.views.first).size.height : mediaQuery.size.height; _screenDensity = mediaQuery.devicePixelRatio == 0.0 ? MediaQueryData.fromView(PlatformDispatcher.instance.views.first).devicePixelRatio : mediaQuery.devicePixelRatio; _statusBarHeight = mediaQuery.padding.top == 0.0 ? MediaQueryData.fromView(PlatformDispatcher.instance.views.first).padding.top : mediaQuery.padding.top; _bottomBarHeight = mediaQuery.padding.bottom == 0.0 ? MediaQueryData.fromView(PlatformDispatcher.instance.views.first).padding.bottom : mediaQuery.padding.bottom; _appBarHeight = kToolbarHeight; } } /// screen width /// 屏幕 宽 double get screenWidth => _screenWidth; /// screen height /// 屏幕 高 double get screenHeight => _screenHeight; /// appBar height /// appBar 高 double get appBarHeight => _appBarHeight; /// screen density /// 屏幕 像素密度 double get screenDensity => _screenDensity; /// status bar Height /// 状态栏高度 double get statusBarHeight => _statusBarHeight; /// bottom bar Height double get bottomBarHeight => _bottomBarHeight; /// media Query Data MediaQueryData? get mediaQueryData => _mediaQueryData; /// screen width /// 当前屏幕 宽 static double getScreenW(BuildContext context) { MediaQueryData mediaQuery = MediaQuery.of(context); return mediaQuery.size.width; } /// screen height /// 当前屏幕 高 static double getScreenH(BuildContext context) { MediaQueryData mediaQuery = MediaQuery.of(context); return mediaQuery.size.height; } /// screen density /// 当前屏幕 像素密度 static double getScreenDensity(BuildContext context) { MediaQueryData mediaQuery = MediaQuery.of(context); return mediaQuery.devicePixelRatio; } /// status bar Height /// 当前状态栏高度 static double getStatusBarH(BuildContext context) { MediaQueryData mediaQuery = MediaQuery.of(context); return mediaQuery.padding.top; } /// status bar Height /// 当前BottomBar高度 static double getBottomBarH(BuildContext context) { MediaQueryData mediaQuery = MediaQuery.of(context); return mediaQuery.padding.bottom; } /// 当前MediaQueryData static MediaQueryData getMediaQueryData(BuildContext context) { MediaQueryData mediaQuery = MediaQuery.of(context); return mediaQuery; } /// 仅支持纵屏。 /// returns the size after adaptation according to the screen width.(unit dp or pt) /// 返回根据屏幕宽适配后尺寸(单位 dp or pt) /// size 单位 dp or pt static double getScaleW(BuildContext context, double size) { if (getScreenW(context) == 0.0) return size; return size * getScreenW(context) / _designW; } /// 仅支持纵屏。 /// returns the size after adaptation according to the screen height.(unit dp or pt) /// 返回根据屏幕高适配后尺寸 (单位 dp or pt) /// size unit dp or pt static double getScaleH(BuildContext context, double size) { if (getScreenH(context) == 0.0) return size; return size * getScreenH(context) / _designH; } /// 仅支持纵屏。 /// returns the font size after adaptation according to the screen density. /// 返回根据屏幕宽适配后字体尺寸 /// fontSize 字体尺寸 static double getScaleSp(BuildContext context, double fontSize) { if (getScreenW(context) == 0.0) return fontSize; return fontSize * getScreenW(context) / _designW; } /// Orientation /// 设备方向(portrait, landscape) static Orientation getOrientation(BuildContext context) { MediaQueryData mediaQuery = MediaQuery.of(context); return mediaQuery.orientation; } /// 仅支持纵屏。 /// returns the size after adaptation according to the screen width.(unit dp or pt) /// 返回根据屏幕宽适配后尺寸(单位 dp or pt) /// size 单位 dp or pt double getWidth(double size) { return _screenWidth == 0.0 ? size : (size * _screenWidth / _designW); } /// 仅支持纵屏。 /// returns the size after adaptation according to the screen height.(unit dp or pt) /// 返回根据屏幕高适配后尺寸(单位 dp or pt) /// size unit dp or pt double getHeight(double size) { return _screenHeight == 0.0 ? size : (size * _screenHeight / _designH); } /// 仅支持纵屏 /// returns the size after adaptation according to the screen width.(unit dp or pt) /// 返回根据屏幕宽适配后尺寸(单位 dp or pt) /// sizePx unit px double getWidthPx(double sizePx) { return _screenWidth == 0.0 ? (sizePx / _designD) : (sizePx * _screenWidth / (_designW * _designD)); } /// 仅支持纵屏。 /// returns the size after adaptation according to the screen height.(unit dp or pt) /// 返回根据屏幕高适配后尺寸(单位 dp or pt) /// sizePx unit px double getHeightPx(double sizePx) { return _screenHeight == 0.0 ? (sizePx / _designD) : (sizePx * _screenHeight / (_designH * _designD)); } /// 仅支持纵屏。 /// returns the font size after adaptation according to the screen density. /// 返回根据屏幕宽适配后字体尺寸 /// fontSize 字体尺寸 double getSp(double fontSize) { if (_screenDensity == 0.0) return fontSize; return fontSize * _screenWidth / _designW; } /// 兼容横/纵屏。 /// 获取适配后的尺寸,兼容横/纵屏切换,可用于宽,高,字体尺寸适配。 /// Get the appropriate size, compatible with horizontal/vertical screen switching, can be used for wide, high, font size adaptation. double getAdapterSize(double dp) { if (_screenWidth == 0 || _screenHeight == 0) return dp; return getRatio() * dp; } /// 适配比率。 /// Ratio. double getRatio() { return (_screenWidth > _screenHeight ? _screenHeight : _screenWidth) / _designW; } /// 兼容横/纵屏。 /// 获取适配后的尺寸,兼容横/纵屏切换,适应宽,高,字体尺寸。 /// Get the appropriate size, compatible with horizontal/vertical screen switching, can be used for wide, high, font size adaptation. static double getAdapterSizeCtx(BuildContext context, double dp) { Size size = MediaQuery.of(context).size; if (size == Size.zero) return dp; return getRatioCtx(context) * dp; } /// 适配比率。 /// Ratio. static double getRatioCtx(BuildContext context) { Size size = MediaQuery.of(context).size; return (size.width > size.height ? size.height : size.width) / _designW; } }