Flutter widget获取位置和大小

1,758 阅读1分钟

移动应用中有很多场景是需要知道布局的大小和位置的,比如控制一个球在一个区域中移动,我们得知道该区域的坐标。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。