A Low-cost Screen adaptation Solution for the Flutter

An overview of

Because the Flutter is used in many different scenarios, not only on Android but also on ios and the Web, there are more and more mobile phone brands and models, so when we write the layout, we will display it differently on different mobile devices. Today we will introduce a solution, which can be a low cost, But one way to restore 100% of the UI is to write the size of the UI design without using utility classes or extension functions to convert

twogithubWelcome to star

Flutter_autosize_screen welcomes star and suggestions

Look at the effect first

Gold mining image layout problem, see Github

IOS

iPhone 8 iPhone 11
iPhone 12 pro max ipad air

android

768×1280-320dpi 10801920-420dpi 1440×2560-560dpi

The web diagram

As you lengthen the screen, the width will gradually become larger than the height, and when it is larger, it will be based on the height.

Three USES

3.1 reference

flutter_autosize_screen: ^{LAST_VERSION}
Copy the code

3.2 the initialization

  1. This is initialized in the first line of the main method. The following reference is usually based on the width of the Ui design. In landscape state, the following 360 is based on the height of the Ui design
void main() {
  // Set the baseline
  AutoSizeUtil.setStandard(360);

  // Use runAutoApp instead of runApp
  // import 'package:flutter_autosize_screen/binding.dart';
  runAutoApp(const MyApp());

}

Copy the code
  1. Replace the MediaQuery of the root MaterialApp
MaterialApp(
      title: 'Autosize Demo'./// So you can get the correct Size later using mediaQuery.of (context)
      builder: AutoSizeUtil.appBuilder,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: HomePage(),
      ),
    )

Copy the code
  1. Get the Size
AutoSizeUtil.getScreenSize()
/ / or
MediaQuery.of(context).size
Copy the code
  1. Write directly according to the size of the design drawing
Container(
    alignment: Alignment.center,
    height: 60,
    width :60,
    color: Colors.redAccent,
    child: Text(
      "Write the dimensions directly according to the design.",),)Copy the code
  1. Bear in mind that

Cannot use the window to get the size or obtain MediaQuery window. PhysicalSize MediaQueryData. FromWindow (Windows)

Four principles

4.1 Flutter Entry runApp(Widget App)

When we call runApp, we do three things: 1. Instantiate the WidgetsFlutterBinding class, 2. To create a component tree attachRootWidget(app), 3. Start the warm-up frame scheduleWarnUpFrame().

voidrunApp(Widget app) { WidgetsFlutterBinding.ensureInitialized() .. scheduleAttachRootWidget(app) .. scheduleWarmUpFrame(); }Copy the code

4.2 WidgetsFlutterBinding

As the name of the class goes, WidgetsFlutterBinding is the bridge between the Binding Widget framework and the Flutter Engine. WidgetsFlutterBinding inherits from BindingBase with many bindings mixed in

class WidgetsFlutterBinding extends BindingBase with GestureBinding.SchedulerBinding.ServicesBinding.PaintingBinding.SemanticsBinding.RendererBinding.WidgetsBinding {
  static WidgetsBinding ensureInitialized() {
    if (WidgetsBinding.instance == null)
      WidgetsFlutterBinding();
    return WidgetsBinding.instance!;
  }
}

Copy the code

4.2.1 Let’s look at the effects of each mixed Binding

  • GestureBinding: provides a window onPointerDataPacket callback, binding Framework gestures subsystem, is the binding Framework model and the underlying events entrance.
  • ServicesBinding: Provides the Window. onPlatformMessage callback for binding to the platform Message channel, which handles both native and Flutter traffic.
  • SchedulerBinding: Provides window.onBeginFrame and window.onDrawFrame callbacks that listen for refresh events and bind to the Framework drawing scheduling subsystem.
  • PaintingBinding: Binding drawing library, mainly used for processing image cache.
  • SemanticsBinding: a bridge between the semantic layer and the Flutter Engine, primarily the underlying support for auxiliary functions.
  • RendererBinding: provides a window. OnMetricsChanged, window. OnTextScaleFactorChanged callback, etc. It is the bridge between the render tree and the Flutter Engine.
  • WidgetsBinding: Provides windows. onLocaleChanged, onBuildScheduled, and other callbacks. It is the bridge between the Flutter Widget layer and the Engine.

4.3 Focus on RendererBinding

So we initialize our first RenderView. RenderView (RenderView) is the root node of the render tree (render tree), and then the render screen (render screen). So we can start with this

void initRenderView() {
    assert(! _debugIsRenderViewInitialized);assert(() {
      _debugIsRenderViewInitialized = true;
      return true; } ()); renderView = RenderView(configuration: createViewConfiguration(),window: window);
    renderView.prepareInitialFrame();
  }

/// Bindings can override this method to change what size or device pixel
/// ratio the [RenderView] will use. For example, the testing framework uses
/// this to force the display into 800x600 when a test is run on the device
/// using `flutter run`.
ViewConfiguration createViewConfiguration() {
    final double devicePixelRatio = window.devicePixelRatio;
    return ViewConfiguration(
      size: window.physicalSize / devicePixelRatio,
      devicePixelRatio: devicePixelRatio,
    );
}
Copy the code

Write a class 4.4 AutoWidgetsFlutterBinding WidgetsFlutterBinding inheritance

Rewrite the createViewConfiguration method to change the devicePixelRatio and screen Size, as follows. Because the devicePixelRatio is adjusted, so for the Event Event, Need additional to the event coordinates for the corresponding proportion of conversion, this can see the source code

class AutoWidgetsFlutterBinding extends WidgetsFlutterBinding {
  static WidgetsBinding ensureInitialized() {
    if (WidgetsBinding.instance == null) AutoWidgetsFlutterBinding();
    returnWidgetsBinding.instance! ; }@override
  ViewConfiguration createViewConfiguration() {
    return ViewConfiguration(
      size: AutoSizeUtil.getSize(),
      devicePixelRatio: AutoSizeUtil.getDevicePixelRatio(),
    );
  }

Copy the code

Thank you for five

  • Flutter Practical Ebook
  • Initialization of the Flutter framework analysis
  • FlutterTest