Flutter计算器应用UI在低分辨率设备溢出,MediaQuery与SafeArea修复无效
问题原因
你的代码存在几个直接导致低分辨率设备显示不全的问题:
- 给body的根Container硬限制了高度为
MediaQuery.of(context).size.height * 0.5,所有界面元素都被塞到只有半个屏幕高的容器里,内容高度超过限制就直接溢出,小屏设备本身可用高度更低,溢出更明显。 - 所有字体、按钮都使用固定像素尺寸,不会根据屏幕大小自适应缩放,小屏设备上固定尺寸的内容很容易超出显示范围。
- Column没有做溢出兼容,内容超出容器高度后没有滚动能力,超出部分直接无法显示。
- 代码嵌套了两层
MaterialApp,属于冗余写法,会干扰全局的尺寸计算逻辑。
修复方案
按照以下步骤修改即可适配低分辨率设备:
- 移除内层多余的
MaterialApp,_GSTCalculatorState的build方法直接返回SafeArea包裹的Scaffold即可。 - 删掉body根Container的固定高度设置,让容器可以自适应可用空间。
- 把Column包裹在
SingleChildScrollView中,内容超出屏幕高度时可以滚动显示,从根本上解决溢出问题。 - 把固定字体尺寸改为按屏幕比例动态计算,比如用屏幕最短边的比例来换算,不同设备自动适配大小。
- 所有按钮行的子元素用
Expanded包裹,自动分配每行宽度,避免按钮文本挤压重叠。
核心修改代码示例
@override Widget build(BuildContext context) { // 提前拿到屏幕尺寸用于动态计算 final screenSize = MediaQuery.of(context).size; // 用屏幕最短边做适配基准,横竖屏都兼容 final shortestSide = screenSize.shortestSide; return SafeArea( child: Scaffold( backgroundColor: const Color(0xFF13131b), appBar: AppBar( title: const Center(child: Text('GST Calculator')), backgroundColor: Colors.black54, ), // 去掉原来的固定高度Container,直接用SingleChildScrollView包裹Column body: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( padding: const EdgeInsets.only(right: 15), // 动态计算字体大小,小屏自动缩小 child: Text('41 x 3', style: TextStyle(fontSize: shortestSide * 0.07, color: Colors.white54),), alignment: Alignment.centerRight, ), Container( padding: const EdgeInsets.all(15), child: Text('123',style: TextStyle(color: Colors.white,fontSize: shortestSide * 0.18),), alignment: Alignment.centerRight, ), Container( color: const Color(0xFF0f0f0f), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ // 每个Gstbutton用Expanded包裹自动分配宽度 Expanded(child: Gstbutton(gstbtntext: 'CHECK ➞', textsize: shortestSide * 0.035,)), Expanded(child: Gstbutton(gstbtntext: 'CORRECT ☒', textsize: shortestSide * 0.035,)), Expanded(child: Gstbutton(gstbtntext: 'CHANGE GST %', textsize: shortestSide * 0.03,)), ], ), ), // 后续所有按钮行都参照上面的写法,按钮用Expanded包裹,字体动态计算 Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Expanded(child: Button(btntext: '3%',btntextsize: shortestSide * 0.045,btncolor: 0xFF0d0d0d,btntextcolor: 0xFF4DE2C8,)), Expanded(child: Button(btntext: '5%',btntextsize: shortestSide * 0.045,btncolor: 0xFF0d0d0d,btntextcolor: 0xFF4DE2C8,)), Expanded(child: Button(btntext: '8%',btntextsize: shortestSide * 0.045,btncolor: 0xFF0d0d0d,btntextcolor: 0xFF4DE2C8,)), Expanded(child: Button(btntext: '18%',btntextsize: shortestSide * 0.04,btncolor: 0xFF0d0d0d,btntextcolor: 0xFF4DE2C8,)), Expanded(child: Button(btntext: '28%',btntextsize: shortestSide * 0.04,btncolor: 0xFF0d0d0d,btntextcolor: 0xFF4DE2C8,)), ], ), // 剩下的其余按钮行都按照上面的逻辑修改即可 ], ), ), ), ); }
如果不想用滚动布局,可以把SingleChildScrollView换成Column,然后给每个行元素包裹Expanded,按比例分配整个屏幕高度,也可以做到完全适配无溢出。
内容的提问来源于stack exchange,提问作者Ashir Ali
相关产品推荐
相关产品推荐

