Flutter获取元素的宽度

214 阅读1分钟

在Flutter中,我们通常会遇到要获取元素宽度的需求,方法有很多种,在此记录一下我在工作中用到的2种方法:

1. 使用LayoutBuilder

LayoutBuilder是一个小部件,它在布局阶段构建小部件,并提供了关于约束的信息。可以使用它来获取父级小部件的约束,然后根据这些约束来确定子小部件的大小。

LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraints) {
    return Container(
      width: constraints.maxWidth,   // constraints.maxWidth 就是父级小部件的宽度
      color: Colors.blue,
    );
  },
)

2. 使用GlobalKeyBuildContext

如果需要在布局完成后获取一个小部件的确切宽度,可以使用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、球状部分通过StackPositioned定位来实现,但是我们知道Positioned的left属性是double类型,不能直接提供一个百分比,所以我用了LayoutBuilder来获取白底的宽度,再通过提供的百分比计算它的left实际值就可以了:constraints.maxWidth * 0.3

image.png