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


Related articles: