Flutter中的不同屏幕尺寸和DPI缩放

3
  @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}) {...}

小型手机像平板一样有一个破解点吗,是否需要建立第三个布局,还是只需根据屏幕大小更正文本和小部件。谢谢。

3个回答

1
这取决于您正在构建的布局的复杂性。例如,在复杂的布局中,当屏幕大小变小时,小部件可能会覆盖其他小部件,或者当它们没有空间时可能会出现像素溢出。尽管Flutter在不同的屏幕上缩放效果良好,但有时这还不够。
我的做法是使用LayoutBuilder小部件,并基于其框约束返回适合其当前约束的屏幕布局。
*请注意,LayoutBuilder小部件从其父级获取其约束条件,因此请确保将其放置在顶部小部件中。
 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();
      }
    },
  ),
);

}


关于字体大小,您可以根据屏幕大小调整大小 Text("text", style: TextStyle(fontSize: screenSize < 300 ? 12 : 16),). - Sergio Bernal
1
另一个选项是将文本包装在FittedBox中,并且不设置文本大小。FittedBox(child: Text("text"))。这将使文本尽可能大地适应其可用空间。 - Sergio Bernal

1
你可以使用这个插件flutter_screenutil,它是一个适用于Flutter的屏幕和字体大小适配插件。让你的UI在不同的屏幕尺寸上显示合理的布局!
初始化并根据系统的“字体大小”可访问选项设置适合的大小和字体大小。请在使用前设置设计稿的宽度和高度,设计稿的宽度和高度(单位px)。一定要将页面设置在MaterialApp的home中(即入口文件,只需设置一次),以确保在每次使用前设置适合的大小。
//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);

使用: # 适应屏幕尺寸: # 传递设计草稿的像素大小:

适应屏幕宽度: ScreenUtil.getInstance().setWidth(540),

适应屏幕高度: ScreenUtil.getInstance().setHeight(200),

您也可以使用ScreenUtil()代替ScreenUtil.getInstance(),例如:ScreenUtil().setHeight(200)

注意

高度也根据setWidth进行适应,以确保没有变形(当您需要正方形时)

setHeight方法主要用于高度适应,您希望控制UI上显示的高度和实际屏幕上的高度相同。

//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),
        ),

适配器字体:
//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),
                )),
          ],
        )

其他相关的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

1
请不要仅仅将某些工具/库或插件作为答案发布。请在回答中至少演示它如何解决问题。 - 4b0
这是一个适用于Flutter的插件,可以自动调整屏幕和字体大小。让你的UI在不同的屏幕尺寸上显示合理的布局! - null

0
我创建了一个小类来确定屏幕大小(额外小,小,中等,大,额外大),并使用简短的名称(xs,sm,md,lg,xl)。
请创建一个名为scree_size_info.dart的新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;
    }
  }
  
}

使用方法:

创建函数:

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;
  }
}

使用 width 属性来设置容器宽度:

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

希望它能对你有所帮助。我在许多Flutter项目中使用了这段代码,它完美地运行着。干杯!!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接