移动应用中有很多场景是需要知道布局的大小和位置的,比如控制一个球在一个区域中移动,我们得知道该区域的坐标。Flutter中UI布局主要是由widget组合实现,故知道怎么获取Widget的位置和大小非常关键。
查看Widget源码,没有发现position和size相关的属性,得通过Widget关联的context获取RenderBox来实现。
我们来看一个Demo,该页面包含一个黑色区域、红色区域和两个按钮。
class PositionAndSizeDemo extends StatelessWidget {
Offset _getPosition() {}
Offset _getSize() {}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(flex: 1, child: Container(color: Colors.black)),
Expanded(flex: 2, child: Container(color: Colors.red)),
SizedBox(height: 40),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RaisedButton(onPressed: _getPosition, child: Text('获取位置')),
RaisedButton(onPressed: _getSize, child: Text('获取大小')),
],
),
SizedBox(height: 40),
],
),
);
}
}
效果如下:
获取大小
要获取红色区域的大小,我们需要给红色区域widget指定一个key。
// 定义key
GlobalKey _redKey = GlobalKey();
...
// 红色区域widget指定key
Expanded(flex: 2, child: Container(key:_redKey, color: Colors.red)),
通过key就可以获取widget的大小了。
_getSize() {
final RenderBox renderBox = _redKey.currentContext.findRenderObject();
final sizeRed = renderBox.size;
print("红色区域大小: $sizeRed");
}
点击获取大小按钮,console可以看到如下结果:
flutter: 红色区域大小: Size(375.0, 461.3)
获取位置
跟获取大小一样,位置也是通过key来获取,代码如下:
_getPosition() {
final RenderBox renderBox = _redKey.currentContext.findRenderObject();
final positionRed = renderBox.localToGlobal(Offset.zero);
print("红色区域位置: $positionRed ");
}
点击获取位置按钮,console可以看到如下结果:
flutter: 红色区域位置: Offset(0.0, 230.7)
localToGlobal方法,获取的结果是该widget左上角在屏幕的位置,宽度占满屏幕所以x坐标是0。