Implementation of Screen Size Adaptation and Font Size Adaptation in flutter
- 2021-11-10 10:59:52
- OfStack
Foreword:
Nowadays, there are more and more brands and models of mobile phones, which leads to different effects displayed on different mobile devices when we usually write layouts.
For example, the size of an View in our design draft is 300px. If you write 300px directly, it may display normally on the current device, but it may be smaller or larger on other devices, which requires us to adapt the screen.
Android native words have their own adaptation rules, and different folders can be established according to different sizes. The system will take the corresponding layout according to the current device size. However, flutter itself has no adaptation rules, and the native one is cumbersome, which requires us to adapt the screen ourselves.
Click to go directly to github address
If it helps, please give me an star
flutter_ScreenUtil
flutter Screen Adaptation Scheme
github: https://github.com/OpenFlutter/flutter_ScreenUtil
Usage:
Installation dependencies:
Please check the latest version before installing
dependencies:
flutter:
sdk: flutter
# Add dependencies
flutter_screenutil: ^0.4.2
Import packages at each place of use:
import 'package:flutter_screenutil/flutter_screenutil.dart';
Initialize setting size
Before using, please set the width and height of the design draft, and the width and height of the passed-in design draft (unit px)
1 Set the page setup in home of MaterialApp (that is, the entry file only needs to be set once) to ensure that the adaptation size is set before each use:
// Set the fit size ( Fill in the screen size of the equipment in the design draft ) If the design draft is based on iPhone6 Designed for the size of (iPhone6 750*1334)
ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context);
Use:
Adaptive size:
px size of passed-in design draft:
Adapt width to screen width: ScreenUtil (). setWidth (540),
Adapt height: ScreenUtil (). setHeight (200) according to screen height,
Attention
The height is also adapted according to setWidth to ensure no deformation (when you want 1 square)
setHeight method is mainly in the height of adaptation, you want to control UI 1 screen height and the actual display of 1 sample used.
For example:
// Rectangle :
Container(
width: ScreenUtil().setWidth(375),
height: ScreenUtil().setHeight(200),
),
// If you want to show 1 Square :
Container(
width: ScreenUtil().setWidth(300),
height: ScreenUtil().setWidth(300),
),
Adapt fonts:
ScreenUtil().setSp(28) // Pass in the font size and scale it according to the font size auxiliary option of the system
ScreenUtil().setSp(28 , false) // The font size passed in is not scaled according to the font size auxiliary option of the system
for example:
Text(
'My font size is 28px and will not change with the system.',
style: TextStyle(
color: Colors.black,
fontSize: ScreenUtil().setSp(28, false)
)
),
Other relevant api:
ScreenUtil.pixelRatio // Pixel density of device
ScreenUtil.screenWidth // Device width
ScreenUtil.screenHeight // Height of equipment
ScreenUtil.bottomBarHeight // Bottom safety zone distance, suitable for full screen with buttons under it
ScreenUtil.statusBarHeight // Height of status bar Liu Haiping will be higher Unit px
ScreenUtil.textScaleFactory // System font scaling
ScreenUtil().scaleWidth // Of the actual width dp And design draft px Proportion of
ScreenUtil().scaleHeight // Actual height dp And design draft px Proportion of
// Import
import 'package:flutter_screenutil/flutter_screenutil.dart';
...
@override
Widget build(BuildContext context) {
// Set the fit size ( Fill in the screen size of the equipment in the design draft ) If the design draft is based on iPhone6 Designed for the size of (iPhone6 750*1334)
ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context);
print(' Device width :${ScreenUtil.screenWidth}'); //Device width
print(' Height of equipment :${ScreenUtil.screenHeight}'); //Device height
print(' Pixel density of device :${ScreenUtil.pixelRatio}'); //Device pixel density
print(
' Distance of bottom safety zone :${ScreenUtil.bottomBarHeight}'); //Bottom safe zone distance , suitable for buttons with full screen
print(
' Height of status bar :${ScreenUtil.statusBarHeight}px'); //Status bar height , Notch will be higher Unit px
print(' Of the actual width dp And design draft px Proportion of :${ScreenUtil().scaleWidth}');
print(' Actual height dp And design draft px Proportion of :${ScreenUtil().scaleHeight}');
print(
' Scale of width and font magnification relative to design draft :${ScreenUtil().scaleWidth * ScreenUtil.pixelRatio}');
print(
' Proportion of height relative to design draft enlargement :${ScreenUtil().scaleHeight * ScreenUtil.pixelRatio}');
print(' Font scaling ratio of the system :${ScreenUtil.textScaleFactory}');
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
Container(
width: ScreenUtil().setWidth(375),
height: ScreenUtil().setHeight(200),
color: Colors.red,
child: Text(
' My width :${ScreenUtil().setWidth(375)}dp',
style: TextStyle(
color: Colors.white,
fontSize: ScreenUtil().setSp(12, false),
),
),
),
Container(
width: ScreenUtil().setWidth(375),
height: ScreenUtil().setHeight(200),
color: Colors.blue,
child: Text(' My width :${ScreenUtil().setWidth(375)}dp',
style: TextStyle(
color: Colors.white,
fontSize: ScreenUtil().setSp(12, false),
)),
),
],
),
Text(' Device width :${ScreenUtil.screenWidth}px'),
Text(' Height of equipment :${ScreenUtil.screenHeight}px'),
Text(' Pixel density of device :${ScreenUtil.pixelRatio}'),
Text(' Distance of bottom safety zone :${ScreenUtil.bottomBarHeight}px'),
Text(' Height of status bar :${ScreenUtil.statusBarHeight}px'),
Text(
' Actual height dp And design draft px Proportion of :${ScreenUtil().scaleHeight}',
textAlign: TextAlign.center,
),
Text(
' Actual height dp And design draft px Proportion of :${ScreenUtil().scaleHeight}',
textAlign: TextAlign.center,
),
Text(
' Scale of width and font magnification relative to design draft :${ScreenUtil().scaleWidth * ScreenUtil.pixelRatio}',
textAlign: TextAlign.center,
),
Text(
' Proportion of height relative to design draft enlargement :${ScreenUtil().scaleHeight * ScreenUtil.pixelRatio}',
textAlign: TextAlign.center,
),
SizedBox(
height: ScreenUtil().setHeight(100),
),
Text(' Font scaling ratio of the system :${ScreenUtil.textScaleFactory}'),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(' My text size is on the design draft 14px Does not vary with the text scaling of the system ',
style: TextStyle(
color: Colors.black,
fontSize: ScreenUtil().setSp(14, false))),
Text(' My text size is on the design draft 14px Will change according to the text scaling ratio of the system ',
style: TextStyle(
color: Colors.black, fontSize: ScreenUtil().setSp(14))),
],
)
],
),
),
);
}
Use example:
example demo
Adaptation principle
Let's talk about the adaptation scheme. For example, the UI designed by our designer is based on Iphone6. We know that the resolution of iPhone6 is 750*1334 (px).
Or UI is designed according to hdpi equipment. We know that Android equipment of hdpi is (240 dpi) and pixel density is 1.5, that is, the resolution width of hdpi equipment is 320px. In short, no matter the unit of design draft is px or dp, we can convert it into px.
Then if we adapt according to px, ios and android can be compatible.
Suppose that our design draft mobile phone is 10801920 px.
There is a 540960 component in the design draft, that is, the width and width is one and a half of the mobile phone. If the size of the component is defined as this when we write it directly, it may not be one and a half, or more or less on other sizes of devices. But we can look at it proportionally, that is, the width we want to achieve is one and a half of the actual device.
So assuming that the widths of our devices are deviceWidth and deviceHeight, we will write components of size: Width: (540/1080) * deviceWidth, Height: (960/1920) * deviceHeight.
From this formula, we can find that the component width we want to write is the size width* (deviceWdith/prototype device width) on the design draft. Then every time we write ui, we only need to directly get the size of the design draft * (deviceWdith/prototype device) width.
The principle is to get the size ratio between the actual equipment and the prototype equipment first.
First, the code for flutter to obtain the size of the device is:
The following data is my mobile phone data:
import 'dart:ui';
// Because window Yes dart:ui Provided in , So you need to import this package .
window.physicalSize //Size(1080.0, 1794.0) Unit px
width = window.physicalSize.width // Width
height = window.physicalSize.height // Height
// Using this method does not require the introduction of packages
MediaQuery.of(context).size //Size(411.4, 683.4) Unit :dp
widhtDp = MediaQuery.of(context).size.width // Width 411.4
heightDp = MediaQuery.of(context).size.height // Height 683.4
When the design unit is px and the size is 1080*1920 px:
scaleWidth = width / 1080;
scaleHeight = height / 1920;
Then the width of the control with the size of 500100 is 500scaleWidth. 100*scaleHeigh. Note that the unit at this time is px, and the default component size unit in flutter is dp. We also need px-
>
Operation of dp. Divide by pixels per inch.
Method for obtaining pixel density by flutter:
MediaQuery.of(context).devicePixelRatio
window.physicalSize
The above two methods get the same result, but the window object comes from dart: ui, so we introduce this package:
import 'package:flutter_screenutil/flutter_screenutil.dart';
0
When the design unit is dp and the size is 360*640 dp:
import 'package:flutter_screenutil/flutter_screenutil.dart';
1
So the width of the control we want to write is 500*100, which is 500*scaleWidth. 100*scaleHeigh