在Flutter中,我们通常会遇到要获取元素宽度的需求,方法有很多种,在此记录一下我在工作中用到的2种方法:
1. 使用LayoutBuilder
LayoutBuilder是一个小部件,它在布局阶段构建小部件,并提供了关于约束的信息。可以使用它来获取父级小部件的约束,然后根据这些约束来确定子小部件的大小。
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Container(
width: constraints.maxWidth, // constraints.maxWidth 就是父级小部件的宽度
color: Colors.blue,
);
},
)
2. 使用GlobalKey和BuildContext
如果需要在布局完成后获取一个小部件的确切宽度,可以使用GlobalKey来引用小部件,并在布局完成后使用RenderBox来获取尺寸。
// 定义一个 GlobalKey
GlobalKey _globalKey = GlobalKey();
// 使用 GlobalKey 构建小部件
Container(
key: _globalKey,
color: Colors.blue,
width: double.infinity, // 或者其他宽度
height: 100,
)
// 在布局完成后获取宽度
void _getWidgetWidth() {
final RenderBox renderBox = _globalKey.currentContext.findRenderObject();
final width = renderBox.size.width;
}
另外再提一个Flutter中的一个widget,在工作中也比较实用:FractionallySizedBox
FractionallySizedBox(
alignment: Alignment.centerLeft,
widthFactor: 0.3, // widthFactor指的是子组件宽度相对于父级组件宽度的一个比例值
child: Container(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
),
),
)
实际例子:
比如实现下面截图中的效果,我们会这样实现:
1、先画底部一条白底;
2、蓝底部分就可以通过FractionallySizedBox来实现;
3、球状部分通过Stack和Positioned定位来实现,但是我们知道Positioned的left属性是double类型,不能直接提供一个百分比,所以我用了LayoutBuilder来获取白底的宽度,再通过提供的百分比计算它的left实际值就可以了:constraints.maxWidth * 0.3