Mobile developers all know that page adaptation needs to be carried out for different mobile phones of different models and sizes, and iOS and Android adaptation schemes are different. How should Flutter development handle screen adaptation?
Units in Flutter
Flutter uses a point similar to the point pt, or point, in iOS. We often say the iPhone8 is 375×667, but its resolution is actually 750×1334. Because the iPhone8 has a pixel ratio of 2.0, the iPhone8plus has a pixel ratio of 3.0.
The size of each iPhone model
Obtain device information from Flutter
To obtain device-related information, you can use an official library
Device_info: ^ 2.0.3Copy the code
Future getDeviceInfo() Async {DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); var dataInfo; If (platform. isIOS) {print(' iOS device: '); IosDeviceInfo iosInfo = await deviceInfo.iosInfo; dataInfo = iosInfo; } else if(platform. isAndroid) {print('Android device '); AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; dataInfo = androidInfo; } return dataInfo; }Copy the code
Gets the screen size
Need to introduce
import 'dart:ui';
Copy the code
Get screen width and height, fringe height, resolution and other information
Final mediaQueryData = MediaQuery. Of (context); / / 2. Get the width and height final screenWidth = mediaQueryData. Size. The width; final screenHeight = mediaQueryData.size.height; final physicalWidth = window.physicalSize.width; final physicalHeight = window.physicalSize.height; final dpr = window.devicePixelRatio; / / 3. The height of the status bar / / a fringe of screen: 44 no bang screen for 20 final statusBarHeight = mediaQueryData. The padding. The top; / / a fringe of screen: 34 no bang screen 0 final bottomHeight = mediaQueryData. The padding. The bottom; Print (' screenWidth :$screenHeight :$screenHeight'); Print (' physicalWidth: $physicalHeight'); Print ($DPR); Print (' statusBarHeight :$bottomHeight');Copy the code
Printed device dimensions
Performing hot restart... Syncing files to device iPhone 12 Pro... Lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua/lua 3.0 Flutter status bar height 47.0 Bottom height 34.0Copy the code
Adaptation scheme
1. By means of equal ratio conversion
Calculation formula: actual size = UI size * device width/design drawing width
This encapsulates a class Adapt that lets you get information about the screen
class Adapt { static double screenWidth = 0; static double screenHeight = 0; static double physicalWidth = 0; static double physicalHeight = 0; static double dpr = 0; Static double ratio = 1.0; static double statusBarHeight = 0; static double bottomHeight = 0; static void initialize(BuildContext context, {double UIWidth = 375}) { // 1. Final mediaQueryData = mediaQuery.of (context); / / 2. Get the width and height of screenWidth = mediaQueryData. Size. The width; screenHeight = mediaQueryData.size.height; physicalWidth = window.physicalSize.width; physicalHeight = window.physicalSize.height; // DPR = window.devicepixelRatio; / / 3. The status bar height / / top bang: 47 pt not bang screen for 20 pt statusBarHeight = mediaQueryData. The padding. The top; / / bottom of bang: 34 pt no bangs screen 0 pt bottomHeight = mediaQueryData. Padding. The bottom; // ratio = screenWidth/UIWidth; } static pt(size){ return size * Adapt.ratio; }}Copy the code
The sample code
The UI gives the design a size of 375 by 667 and defines a (300 by 300)pt box to display 30pt text
@override Widget build(BuildContext context) { Adapt.initialize(context); Return Scaffold(appBar: appBar (title: const Text(' screen fit '),), body: Center(Child: Container(width: Adapt.pt(300), height: Adapt.pt(300), color: Colors.orange, alignment: Alignment.center, child: Text( 'Hello Word', style: TextStyle(fontSize: Adapt.pt(30)), textAlign: TextAlign.center, ), ), ), ); }Copy the code
Run the effect diagram, obviously on the right to do more in line with the effect
2. RPX scheme adaptation
RPX is a fit in the applet. It uses 750px as the design, 1rpx= screen width /750, and all other units are RPX units.
- Whatever screen it is, 750 pieces
- On iPhone8:1rpx = 375/750 = 0.5px
- On iPhone12proMax: 1rpx = 428/750 = 0.571px
You can calculate an RPX by multiplying your size and RPX units: 300px width: 3002rpx
- It worked out on the iPhone8
300px
- The result was calculated on the iPhone12proMax
342.6 px.
As you can see from the calculations, there are significant statistical differences.
Here, too, we encapsulate a class Adapt that directly captures the information on the screen
class Adapt { static MediaQueryData _mediaQueryData = MediaQueryData(); static double screenWidth = 0; static double screenHeight = 0; static double rpx = 0; static double px = 0; static void initialize(BuildContext context, {double standardWidth = 750}) { _mediaQueryData = MediaQuery.of(context); screenWidth = _mediaQueryData.size.width; screenHeight = _mediaQueryData.size.height; rpx = screenWidth / standardWidth; px = screenWidth / standardWidth * 2; } // Static double setPx(double size) {return adapt. RPX * size * 2; } // Set static double setRpx(double size) {return Adapt. RPX * size; }}Copy the code
The sample code
And the above requirements are the same, the final effect of adaptation is the same
@override Widget build(BuildContext context) { Adapt.initialize(context); Return Scaffold(appBar: appBar (title: const Text(' screen fit '),), body: Center(Child: Container(width: Adapt.setPx(300), height: Adapt.setPx(300), color: Colors.orange, alignment: Alignment.center, child: Text( 'Hello Word', style: TextStyle(fontSize: Adapt.setPx(30)), textAlign: TextAlign.center, ), ), ), ); }Copy the code
Note: The context must be used in the Widget that already has the MaterialApp, otherwise it will not work. I’ve defined the default size of the renderer to be 375*667, where you can customize the width of the renderer.
3. Flutter_screenutil plug-in
- Pubspec. Introduced in yaml
Flutter_screenutil: ^ 5.0.1Copy the code
- Initialize the Widget with the Context in the Widget that already has the MaterialApp
ScreenUtil.init(context, width: 750, height: 1334, allowFontScaling: false);
Copy the code
The sample code
Container(
width: ScreenUtil().setWidth(300),
height: ScreenUtil().setHeight(300)
}
Copy the code
Text(
'Hello Word',
style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(30)),
textAlign: TextAlign.center,
)
Copy the code
For more information, please refer to pub.flutter-io.cn/packages/fl…
Not clear in the UI design px, pt, ppi, dpi, dp, the relationship between the sp can refer to this article: www.jianshu.com/p/2871c48c6…