Flutter如何让叠加在图片上的按钮位置根据屏幕尺寸自动适配?
问题原因
你现在用固定像素值top:385, left:17做定位,不同设备的屏幕宽度、像素密度不一样,图片按BoxFit.fitWidth缩放后,实际显示的宽高会和你当初写固定值的测试设备不一样,自然就会出现偏移。
适配方案
核心逻辑是把绝对坐标转换成相对于图片实际显示尺寸的比例坐标,不管图片缩放多少,比例是固定的,按钮位置就不会错位,具体实现步骤如下:
- 先获取素材的原始尺寸
查看你的assets/oral_structure.png的原始宽高,记为originImgWidth(原始宽度)、originImgHeight(原始高度),可以直接在电脑上查看图片属性拿到这两个值。 - 计算按钮的相对比例
你当前的固定定位值是针对原始图片的坐标,对应比例计算如下:
// 左侧相对比例 = 原始图上按钮的left值 / 原始图宽度 double leftRatio = 17 / originImgWidth; // 顶部相对比例 = 原始图上按钮的top值 / 原始图高度 double topRatio = 385 / originImgHeight;
- 动态计算实际定位值
用LayoutBuilder拿到父容器的尺寸,结合比例计算最终的定位值,完整实现代码如下:
// 替换为你自己的图片原始宽高 final double originImgWidth = 你的图片原始宽度; final double originImgHeight = 你的图片原始高度; @override Widget build(BuildContext context){ return Scaffold( backgroundColor: Colors.white, body: LayoutBuilder( builder: (context, constraints) { // 图片实际显示宽度 = 父容器宽度 double actualImgWidth = constraints.maxWidth; // 图片实际显示高度 = 原始高宽比 * 实际宽度 double actualImgHeight = (originImgHeight / originImgWidth) * actualImgWidth; // 计算按钮实际定位值 double buttonLeft = leftRatio * actualImgWidth; double buttonTop = topRatio * actualImgHeight; return Stack( fit: StackFit.expand, children: <Widget>[ Image( image: AssetImage("assets/oral_structure.png"), fit: BoxFit.fitWidth ), Positioned( top: buttonTop, left: buttonLeft, child: TextButton( style: TextButton.styleFrom( shape: const CircleBorder(), ), child: Text('ㅂ', style: TextStyle( fontSize: actualImgWidth * 0.08, // 按宽度比例设置字号,适配不同屏幕 fontWeight: FontWeight.bold )), onPressed: (){ Navigator.push(context, MaterialPageRoute(builder: (context) => B()),); }, ) ), ], ); } ), ); }
注:示例中替换了已经废弃的
FlatButton为Flutter新版本推荐的TextButton,如果你的项目使用的是旧版本Flutter,可以换回FlatButton即可。如果有多个按钮,只需要提前计算每个按钮对应的比例,分别计算定位值即可,同时该方案也支持横竖屏切换自动适配。
内容的提问来源于stack exchange,提问作者eno2
相关产品推荐
相关产品推荐

