Flutter screen adaptation

Github project address: VPixel

There are only two types of mobile UI adaptation

  • Multiple UI dynamic responses
  • Single UI isometric scaling

Here’s a look at some of the more common single-UI scaling.

In the Flutter, the default pixel unit is DP. Due to the inconsistency between the size and resolution of mobile devices, there are visual differences between different devices. This problem can be achieved by scaling according to the absolute width of the design drawing.

The adaptation process

Due to the release of the official version of the Web, Desktop (PS: can manually adjust the interface size), the SIZE of the UI has become more diversified

Processing flow

  1. Respond to changes in UI size

By registering listeners, you can learn about UI size changes

// WidgetsBindingObserver's didChangeMetrics function is called back when the UI size changes
WidgetsBinding.instance.addObserver(WidgetsBindingObserver observer);
Copy the code
  1. Changing the scaling ratio

The didChangeMetrics function tells us the UI size change, and here we do the scaling of the change

// Get the latest UI size data
final data = MediaQueryData.fromWindow(WidgetsBinding.instance?.window);
// Scale ratio = data.sie.width/design size;
Copy the code
  1. Notify UI rebuild

Finally, the notification refresh is done through the setState function

Implementation can see the project source code, or later decomposition ~ ~ ~

use

  1. Import the project
dependencies:
  # Virtual pixels
  vpixel:
    git:
      url: https://github.com/XiaoBaiCZ/vPixel.git
      ref: stable
Copy the code
  1. Use VPixel to wrap widgets that need to be scaled, recommended entry widgets (universal)
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Set the entry to VPixel
    return VPixel(
      // The width of the design draft
      designWidth: 750,
      builder: (ctx) {
        // The original entry Widget
        // VPX can be used in all App scopes, such as Body
        returnMaterialApp( home: Scaffold( body: Body(), ), ); }); }}// VPX can be used to fill in the size of the design draft within App range
class Body extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.center,
      children: [
        //3 equally divided squares
        // VPX can be used to fill in the size of the design draft within App range
        Positioned(
          top: 0,
          left: 0,
          child: Container(color: Colors.red, width: 250.vpx, height: 250.vpx,),
        ),
        Positioned(
          top: 0,
          child: Container(color: Colors.green, width: 250.vpx, height: 250.vpx,),
        ),
        Positioned(
          top: 0,
          right: 0,
          child: Container(color: Colors.blue, width: 250.vpx, height: 250.vpx,),
        ),
        //2 equally divided squares
        Positioned(
          bottom: 0,
          left: 0,
          child: Container(color: Colors.yellow, width: 375.vpx, height: 375.vpx,),
        ),
        Positioned(
          bottom: 0,
          right: 0,
          child: Container(color: Colors.orange, width: 375.vpx, height: 375.vpx,), ), ], ); }}Copy the code
  1. rendering