简体   繁体   中英

Different Screen size and dpi scaling in Flutter

  @override
  Widget build(BuildContext context) {

    final double shortesSide = MediaQuery.of(context).size.shortestSide;
    final bool useMobileLayout = shortesSide <= 600.0; //use this for mobile
    final Orientation orientation = MediaQuery.of(context).orientation;

    return Scaffold(
      resizeToAvoidBottomPadding: false,
      backgroundColor: Color.fromRGBO(246, 246, 246, 1.0),
      appBar: AppBar(
          backgroundColor: Color.fromRGBO(121, 85, 72, 1.0),
          centerTitle: true,
          title: Text(...),
          leading: IconButton(
            onPressed: () {
              Navigator.pushReplacementNamed(context, 'Menu');
            },
            icon: Icon(
              Icons.arrow_back,
              color: Colors.white,
            ),
          )),
      body: useMobileLayout
          ? _buildPhoneView(orientation: orientation)
          : _buildTabletView(orientation: orientation),
    );
  }



//phone
  Container _buildPhoneView({@required Orientation orientation}) {...}

//tablet
  Container _buildTabletView({@required Orientation orientation}) {...}

Is there a breaking point for smaller phones like for tablets <600? Do I need to build third layout or I can just correct text and widget based on screen size. Thank you

It depends of the complexity of the layout you're building. For example with complex layouts, when the screen size gets smaller, widgets might cover other widgets or a pixel overflow could appear when they have no room. Even though Flutter scales well on different screens, sometimes that is not enough.

What I do is using the LayoutBuilder Widget, and based on its box Constraints, I return a layout for a screen that fits its current constraints.

*Note that the LayoutBuilder widget takes its constraints from its parent, so make sure you put it as a top widget.

 Widget build(BuildContext context) {
  return Scaffold(
  appBar: AppBar(
    title: Text(widget.title),
  ),
  body: LayoutBuilder(
    builder: (context, constraints) {
      if (constraints.maxWidth < 600) {
        return SmallPage();
      } else {
        return BigPage();
      }
    },
  ),
);

}

you can use this plugin flutter_screenutil . It is a flutter plugin for adapting screen and font size.Let your UI display a reasonable layout on different screen sizes!

Initialize and set the fit size and font size to scale according to the system's "font size" accessibility option # Please set the width and height of the design draft before use, the width and height of the design draft (unit px). Be sure to set the page in the MaterialApp's home(ie the entry file, just set it once) to ensure that the fit size is set before each use:

//fill in the screen size of the device in the design

//default value : width : 1080px , height:1920px , 
allowFontScaling:false
ScreenUtil.instance = ScreenUtil.getInstance()..init(context);

//If the design is based on the size of the iPhone6 ​​(iPhone6 ​​750*1334)
ScreenUtil.instance = ScreenUtil(width: 750, height: 
1334)..init(context);

//If you wang to set the font size is scaled according to the system's 
"font size" assist option
ScreenUtil.instance = ScreenUtil(width: 750, height: 1334, 
allowFontScaling: true)..init(context);

Use: # Adapt screen size: # Pass the px size of the design draft:

Adapted to screen width: ScreenUtil.getInstance().setWidth(540),

Adapted to screen height: ScreenUtil.getInstance().setHeight(200),

You can also use ScreenUtil() instead of ScreenUtil.getInstance(), for example:ScreenUtil().setHeight(200)

Note

Height is also adapted according to setWidth to ensure no deformation (when you want a square)

setHeight method is mainly adapted in height, you want to control the height and actuality of a screen on the UIUsed when the same is displayed.

//for example:
//rectangle
Container(
       width: ScreenUtil.getInstance().setWidth(375),
       height: ScreenUtil.getInstance().setHeight(200),
       ...
        ),

////If you want to display a square:
Container(
       width: ScreenUtil.getInstance().setWidth(300),
       height: ScreenUtil.getInstance().setWidth(300),
        ),

Adapter font:

//Incoming font size,the unit is pixel, fonts will not scale to 
respect Text Size accessibility settings
//(AllowallowFontScaling when initializing ScreenUtil)
ScreenUtil.getInstance().setSp(28)    

//Incoming font size,the unit is pixel,fonts will scale to respect Text 
Size accessibility settings
//(If somewhere does not follow the global allowFontScaling setting)
ScreenUtil(allowFontScaling: true).setSp(28)  

//for example:

Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
                'My font size is 24px on the design draft and will not change with the system.',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: ScreenUtil.getInstance().setSp(24),
                )),
            Text(
                'My font size is 24px on the design draft and will change with the system.',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: ScreenUtil(allowFontScaling: true).setSp(24),
                )),
          ],
        )

Other related apis:

ScreenUtil.pixelRatio       //Device pixel density
ScreenUtil.screenWidth      //Device width
ScreenUtil.screenHeight     //Device height
ScreenUtil.bottomBarHeight  //Bottom safe zone distance, suitable for buttons with full screen
ScreenUtil.statusBarHeight  //Status bar height , Notch will be higher Unit px
ScreenUtil.textScaleFactory //System font scaling factor

ScreenUtil.getInstance().scaleWidth //Ratio of actual width dp to design draft px
ScreenUtil.getInstance().scaleHeight //Ratio of actual height dp to design draft px

I have created a small class to determine screen size. (Extra small, Small, Medium, Large, Extra Large) with short names (xs, sm, md, lg, xl)

Create new dart file name as scree_size_info.dart

import 'dart:math';
import 'package:flutter/material.dart';

enum ScreenSize { xs, sm, md, lg, xl, unknown }

class ScreenInfo {
  static Size size(BuildContext c) => MediaQuery.of(c).size;

  static double diagonal(BuildContext c) {
    Size s = size(c);
    return sqrt((s.width * s.width) + (s.height * s.height));
  }

  static ScreenSize screenSize(BuildContext context) {
    double diagonalValue = diagonal(context);
    if (diagonalValue >= 0 && diagonalValue <= 599) {
      return ScreenSize.xs;
    } else if (diagonalValue >= 600 && diagonalValue <= 1023) {
      return ScreenSize.sm;
    } else if (diagonalValue >= 1023 && diagonalValue <= 1439) {
      return ScreenSize.md;
    } else if (diagonalValue >= 1440 && diagonalValue <= 1919) {
      return ScreenSize.lg;
    } else if (diagonalValue >= 1920) {
      return ScreenSize.xl;
    } else {
      return ScreenSize.unknown;
    }
  }

  static bool isExtraSmall(BuildContext context) {
    double diagonalValue = diagonal(context);
    if (diagonalValue >= 0 && diagonalValue <= 599) {
      return true;
    } else {
      return false;
    }
  }

  static bool isSmall(BuildContext context) {
    double diagonalValue = diagonal(context);
    if (diagonalValue >= 600 && diagonalValue <= 1023) {
      return true;
    } else {
      return false;
    }
  }

  static bool isMedium(BuildContext context) {
    double diagonalValue = diagonal(context);
    if (diagonalValue >= 1023 && diagonalValue <= 1439) {
      return true;
    } else {
      return false;
    }
  }

  static bool isLarge(BuildContext context) {
    double diagonalValue = diagonal(context);
    if (diagonalValue >= 1440 && diagonalValue <= 1919) {
      return true;
    } else {
      return false;
    }
  }

  static bool isExtraLarge(BuildContext context) {
    double diagonalValue = diagonal(context);
    if (diagonalValue >= 1920) {
      return true;
    } else {
      return false;
    }
  }
  
}

Usage:

create function:

double boxWidth(BuildContext ctx){
  if(ScreenInfo.screenSize(ctx) == ScreenSize.xl ||
      ScreenInfo.screenSize(ctx) == ScreenSize.md ||
      ScreenInfo.screenSize(ctx) == ScreenSize.lg) {
    return 100;
  } else {
    return 30;
  }
}

use width for container:

Container(
   width: boxWidth(context),
   color: Colors.white,
   padding: const EdgeInsets.all(5),
)

I hope it will help you. I have used this code in many flutter projects and it works perfectly. Cheers!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM