Due to the diversity of mobile devices, especially Android, which is highly fragmented and has various resolutions, and the cross-platform development of Flutter needs to support both Android and iOS. In order to restore the design effect and improve user experience as much as possible, screen adaptation is necessary.

Currently, there is no official screen adaptation solution for Flutter. Most of the current adaptation solutions for Flutter project development are proportional adaptation, which is a universal adaptation method. This adaptation method is also widely used in front-end, Android, iOS and applets development.

The principle of

UI design is usually based on a fixed size, such as 360 x 690. The actual device resolution may be Google Pixel: 1080 x 1920, Google Pixel XL: 1440 x 2560, iPhone 12 Pro Max: 1284 x 2778, etc. If you directly write down the value in accordance with the design drawing during development, the final effect will be inconsistent with the design effect. At this point you can use a proportional way to adapt.

Divide the design drawing into fixed units and define an identifier for this unit, such as W. Then, by obtaining the device resolution, divide the real width of the device by the width of the design drawing, and obtain the true width of 1W:

1W = Actual device width/design drawing width

If the size of the design drawing is 360 x 690, the width is 360 W. If the width of the real device is 1080, 1W = 1080/360 = 3.

According to the above algorithm, the true width of 1W of the corresponding device can be obtained:

Google Pixel: 1w = 1080 / 360 = 3

Google Pixel XL: 1W = 1440/360 = 4

IPhone 12 Pro Max: 1W = 1284/360 = 3.57

According to the same algorithm, the height can be defined as a unit h, and the real value of the height unit of the corresponding device can be obtained as follows:

Google Pixel: 1H = 1920/690 = 2.78

Google Pixel XL: 1H = 2560/690 = 3.71

IPhone 12 Pro Max: 1H = 2778/690 = 4.03

After obtaining the true values of W and H after conversion, the development process can use it to set the height, width and spacing of UI controls, so that the final effect is infinitely close to the effect of the design.

In the development process, the width is generally used for adaptation, the control height is either adaptive, or also set the width unit, and then the overall height is adaptive according to the content. But if there are special requirements can also be used to adapt height, such as the requirement that the banner occupies 1/4 of the screen, or the content is just a screen display, this time to set the height of the control can be used to adapt height units.

Based on the above algorithm, the corresponding adaptation scheme can be realized in the project. However, in order to avoid repeated wheel building, the adaptation library flutter_screenUtil can be directly used in the project development.

flutter_screenutil

Flutter_screenutil is a screen adaptation library based on the above proportional adaptation principle. The latest version is 5.0.1 and has a 2.8K star on GitHub. Pub. dev has 1536 likes, 130 pub index and 99% popularity, indicating that it is a reliable wheel.

Flutter_screenutil: Make your UI layout sound on different screen sizes!

Add the dependent

Add the flutter_screenutil dependency to pubspec.yaml in the project root directory:

dependencies:
  flutter:
    sdk: flutter
  Add a dependency
  flutter_screenutil: ^ 5.0.1
Copy the code

Initialize the

Flutter_screenutil provides two methods for initialization: ScreenUtilInit and ScreenUtil. Init. First import the package where it is used:

import 'package:flutter_screenutil/flutter_screenutil.dart';
Copy the code
ScreenUtilInit

To initialize in ScreenUtilInit mode, the MaterialApp of the project needs to be wrapped, and then the MaterialApp of the project itself is returned in Builder. Pass in the designSize parameter of ScreenUtilInit the size of the design diagram as follows:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
      designSize: Size(360.690), // Pass in the design dimensionsbuilder: () => MaterialApp( ... ) ,); }}Copy the code
ScreenUtil.init

Flutter_screenutil is initialized using the screenUtil. init method, passing in the screen size, design size, and screen orientation.

ScreenUtil.init(
  BoxConstraints(
    maxWidth: MediaQuery.of(context).size.width,  // Screen width
    maxHeight: MediaQuery.of(context).size.height, // Screen height
  ),
  designSize: const Size(360.690), // Design dimensions
  orientation: Orientation.portrait); // Screen orientation
Copy the code

To use this method, you only need to initialize it before using Flutter_screenUtil, which is usually done when the root route (the first page) loads.

Note: Screenutil. init cannot be initialized in MyApp, No MediaQuery ancestor could be found starting from the context that was passed to mediaquery.of (). This can happen because you have not added a WidgetsApp, CupertinoApp, or MaterialApp widget (those widgets introduce a MediaQuery), or it can happen if the context you use comes from a widget above those widgets. Mediaquery.of (context) cannot be used to get the screen width because the MaterialApp has not been loaded at this point

Regarding the above two initialization methods, the author of Flutter_screenUtil recommends using the second method.

use

After initialization, you can use the methods provided by Flutter_screenUtil to get the adjusted values and use them.

You can use the following API to obtain the width and height and font matching values:

ScreenUtil().setWidth(540)  // Adjust the size according to the screen width
ScreenUtil().setHeight(200) // Adjust the size according to the screen height (generally according to the width)
ScreenUtil().radius(200)    // Adjust according to the smaller of the width or height
ScreenUtil().setSp(24)      // Font size fit
Copy the code

The parameter passed in is the size on the design diagram. Examples in actual use are as follows:

Container(
  width: ScreenUtil().setWidth(200),
  height: ScreenUtil().setHeight(540),
  child: Text("Hello", style: TextStyle(fontSize: ScreenUtil().setSp(24))));Copy the code

This allows you to develop with matching values.

But it turns out that it’s too cumbersome to write a long string of code in order to get a match. Flutter_screenutil provides a more concise call method. The Dart extension extends a set of attributes for num to be easily called by developers. The above API can be converted by extending attributes as follows:

ScreenUtil().setWidth(540) = >540.h
ScreenUtil().setHeight(200) = >200.w
ScreenUtil().radius(200) = >200.r
ScreenUtil().setSp(24) = >24.sp
Copy the code

The following is an example after modification:

Container(
  width: 200.w,
  height: 540.h,
  child: Text("Hello", style: TextStyle(fontSize: 24.sp),),
);
Copy the code

That’s a lot simpler.

Note: according to the adaptation principle explained above, in general, 1. W! = 1.h, unless the screen resolution ratio is exactly the same as the design scale, so if you want to set a square, remember to use the same unit, such as the same W or H, otherwise it may be displayed as a rectangle.

In addition to the above four extended attributes, sm, sw and SH are also provided

  • sm: Takes the value itself andspThe smallest value of the value of, e.g12.smThen take the1212.spAnd take the smallest value.
  • sw: short for screen width, returns a value proportional to the screen width. Such as0.2. SwReturns 20% of the screen width,1.swIt’s the entire screen width
  • sh: short for screen height, similar to sw, returns the screen height of a specified proportion. Such as1.shIs the entire screen height

If sp is used as the font unit, it will change with the system font scaling by default. If you do not want the font to change with the system font scaling, you can set textScaleFactor to 1.0 to achieve this. The MaterialApp can be set globally or Text can be set separately in the project:

Global Settings:

MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter_ScreenUtil',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        builder: (context, widget) {
          return MediaQuery(
            ///The text size does not change with system Settings
            data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
            child: widget,
          );
        },
        home: HomePage(title: 'FlutterScreenUtil Demo'),),Copy the code

Text Set separately:

Text("text", textScaleFactor: 1.0)
Copy the code

The effect

Attached is the official rendering:

Other apis

In addition to the adaptation API, Flutter_screenUtil provides a number of useful apis, such as the following:

  • ScreenUtil().pixelRatio: Pixel density of the device
  • ScreenUtil().screenWidth: Screen width, equivalent to1.sw
  • ScreenUtil().screenHeight: Screen height, equal to1.sh
  • ScreenUtil().bottomBarHeight: Bottom navigation height, such as the height of a full-screen bottom button
  • ScreenUtil().statusBarHeight: Status bar height
  • ScreenUtil().textScaleFactor: System font scale
  • ScreenUtil().scaleWidth : Ratio of the actual width to the width of the design drawing
  • ScreenUtil().scaleHeight: The ratio of the actual height to the height on the design drawing
  • ScreenUtil().orientation: Screen orientation

Source: flutter_app_core

Flutter_screenutil library source: flutter_screenutil

Review: @ seven color xiangyun Zhi Zunbao

The application framework of Flutter

  • GetX integration and Usage of Flutter application framework
  • Frame construction of Flutter application (2) Screen adaptation