内容简介:我遇到过很多人问,如何在屏幕上获取Widgets 的 size 和 position 的问题。在某些情况下,我们会发现我们总是会有一些原因需要去实现这个功能。但是 Widget本身是没有 size 和 position。为了实现这一点,我们必须获得与Widget上下文相关联的RenderBox。我们可以创建一个demo,在Column中画3个不同颜色的面板,分别是红、紫、绿,再在底部写两个按钮分别是 Get Sizes, Get Position.
原文链接 作者: Diego Velasquez 喜欢理由:可以更好的调试布局问题
我遇到过很多人问,如何在屏幕上获取Widgets 的 size 和 position 的问题。在某些情况下,我们会发现我们总是会有一些原因需要去实现这个功能。但是 Widget本身是没有 size 和 position。为了实现这一点,我们必须获得与Widget上下文相关联的RenderBox。
How do we do this?
我们可以创建一个demo,在Column中画3个不同颜色的面板,分别是红、紫、绿,再在底部写两个按钮分别是 Get Sizes, Get Position.
demo 代码片段
_getSizes() { } _getPositions(){ } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( ), body: Column( children: <Widget>[ Flexible( flex: 2, child: Container( color: Colors.red, ), ), Flexible( flex: 1, child: Container( color: Colors.purple, ), ), Flexible( flex: 3, child: Container( color: Colors.green, ), ), Spacer(), Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ MaterialButton( elevation: 5.0, padding: EdgeInsets.all(15.0), color: Colors.grey, child: Text("Get Sizes"), onPressed: _getSizes, ), MaterialButton( elevation: 5.0, color: Colors.grey, padding: EdgeInsets.all(15.0), child: Text("Get Positions"), onPressed: _getPositions, ) ], ), ) ], ), ); } 复制代码
效果图:
现在的问题是:我如何得到每个面板的 size 和 position?
让我们先关注上面的红面板,当我们知道如何获取它的 size 和 position,那么对于其他面板也就迎刃而解了。
获取 Widget 的 Size
为了实现这个,我们需要让我们的Widget有一个Key,所以我们要创建一个GlobalKey并赋值给我们的Widget
//creating Key for red panel GlobalKey _keyRed = GlobalKey(); ... //set key Flexible( flex: 2, child: Container( key: _keyRed, color: Colors.red, ), ), 复制代码
一旦我们Widget 有了 Key,我们就能通过下面的方式根据Key去获取size。
_getSizes() { final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject(); final sizeRed = renderBoxRed.size; print("SIZE of Red: $sizeRed"); } 复制代码
如果我们点击 Get Sizes 按钮,在控制台将显示
flutter: SIZE of Red: Size(375.0, 152.9) 复制代码
现在我们知道 红色面板的宽高分别是 375.0 152.9
很简单对吧,让我们继续获取Widget所处的位置信息
获取Widget的位置
与之前的方式一样,我们的Widget必须有一个Key值,我们更新一下获取Widget位置的方法,来获取Widget 相对于定义位置左上角的位置(在这个例子中,我们使用 0.0来表示当前屏幕的左上角)
_getPositions() { final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject(); final positionRed = renderBoxRed.localToGlobal(Offset.zero); print("POSITION of Red: $positionRed "); } 复制代码
如果点击 Get Positions 按钮,将在控制台打印出:
flutter: POSITION of Red: Offset(0.0, 76.0) 复制代码
这说明我们的Widget 在X轴上是0.0 在Y轴上是76.0(在屏幕的左上角)
为什么是76.0?那是因为在这个例子中上面有个高度为76.0的AppBar
哇~ 到这里,我们已经知道如何去获取Widget的 size 和 position
But~ 如果我想在开始的时候就得到 size 和 position,而不是通过按钮的的点击获取,该如何?
那么试试在构造函数中调用我们的方法
_MainSizeAndPositionState(){ _getSizes(); _getPositions(); } 复制代码
运行一下demo,会出现错误信息
flutter: The following NoSuchMethodError was thrown building Builder: flutter: The method 'findRenderObject' was called on null. flutter: Receiver: null flutter: Tried calling: findRenderObject() 复制代码
那么我们试试从InitState中调用会怎么样
@override void initState() { _getSizes(); _getPositions(); super.initState(); } 复制代码
运行一下demo,与刚才有点不一样,但还是报错
flutter: Another exception was thrown: NoSuchMethodError: The method 'findRenderObject' was called on null. 复制代码
那我们要在开始的时候获取大小和位置该如何去做呢?
上面报错的原因是因为我们的state还没有得到相应的context。
以下网址可以找到更多的信息关于Widget的生命周期 medium.com/flutter-com… ,掘金上有一篇翻译的,但是作者与来源不一样,内容差不多,可以参考 juejin.im/post/5c768a…
因此我们必须等待Widget完成渲染后,再执行。但是该怎么做?
下面有个简单的实现方式:
@override void initState() { WidgetsBinding.instance.addPostFrameCallback(_afterLayout); super.initState(); } _afterLayout(_) { _getSizes(); _getPositions(); } 复制代码
这样就可以确保布局渲染完成后去调用你的方法
再运行一次demo,将会得到:
flutter: SIZE of Red: Size(375.0, 152.9) flutter: POSITION of Red: Offset(0.0, 76.0) 复制代码
最后!!!
你也可以回顾一下我朋友 Simon Lightfoot 创建的package pub.dartlang.org/packages/af…
总结
很多次我们都会把简单的事情搞得非常复杂。所以仔细阅读Flutter提供的官方文档其实很有必要,毕竟我们每天都在学习新的东西。
你可以在我的 flutter-samples repo中查看我的源代码 github.com/diegovelope…
以上所述就是小编给大家介绍的《[译]Flutter: Widget Size and Position》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
产品经理面试宝典
[美] Gayle Laakmann McDowell、[美]Jackie Bavaro / 吴海星、陈少芸 / 人民邮电出版社 / 2015-3 / 59.00元
本书针对IT 行业产品经理,以面试为主线,首先介绍产品经理职责以及谷歌、微软等知名企业中产品经理的作用和要求;然后采访了几位知名企业的产品经理,介绍成为产品经理的基本素质;之后从简历准备、各公司面试要点到具体面试问题进行详细分析,这部分是本书的重点内容。读者对象包括IT 行业产品经理以及对如何做好产品有兴趣的人士。一起来看看 《产品经理面试宝典》 这本书的介绍吧!