Reputation: 2683
I came across this example to get the size/position of a widget: https://medium.com/@diegoveloper/flutter-widget-size-and-position-b0a9ffed9407
What is wrong with my code?
I get the error:
The following NoSuchMethodError was thrown while handling a gesture:
I/flutter ( 8566): The method 'findRenderObject' was called on null.
I/flutter ( 8566): Receiver: null
I/flutter ( 8566): Tried calling: findRenderObject()
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: MyWidgetSizeTMP());
}
}
class MyWidgetSizeTMP extends StatefulWidget{
@override
MyWidgetSizeTMPState createState() {
return new MyWidgetSizeTMPState();
}
}
class MyWidgetSizeTMPState extends State<MyWidgetSizeTMP> {
//creating Key for red panel
GlobalKey _keyRed = GlobalKey();
_getSizes() {
final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject();
final sizeRed = renderBoxRed.size;
print("SIZE of Red: $sizeRed");
}
_getPositions() {
final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject();
final positionRed = renderBoxRed.localToGlobal(Offset.zero);
print("POSITION of Red: $positionRed ");
}
_afterLayout(_) {
_getSizes();
_getPositions();
}
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
}
@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,
)
],
),
)
],
),
);
}
}
Upvotes: 15
Views: 42470
Reputation: 736
There isn't any direct way to calculate the size of the widget, so to find that we have to take the help of the context of the widget.
Calling context.size returns us the Size object, which contains the height and width of the widget. context.size calculates the render box of a widget and returns the size.
Checkout Flutter: How to get the height of the widget?
Upvotes: 0
Reputation: 933
In the link you referred to, after creating the GlobalKey it is assigned to the red container.
But in your code you haven't assigned it to the container, so it can be referred to from the _getSizes() and _getPositions(), _keyRed have to be attached to a Context in your code before you use it.
// Creating Key for red panel
GlobalKey _keyRed = GlobalKey();
...
// Set key
Flexible(
flex: 2,
child: Container(
key: _keyRed, // Assigned as a key of the red container.
color: Colors.red,
),
),
Upvotes: 2
Reputation: 51186
This is because the _keyRed
is not attached to Context in your code.
To fix it:
@override
Widget build(BuildContext context) {
return Scaffold(
key: _keyRed, // Add this.
appBar: AppBar(
Upvotes: 8
Reputation: 1404
Get the size of the current widget with RenderBox. Read all the properties RenderBox can offer you.
Code to get the height:
class _YourWidgetState extends State<YourWidget> {
// Remember to assign this key to a widget.
late final GlobalKey _key = GlobalKey();
...
Widget build(BuildContext context) {
var renderBox = null;
if (_key.currentContext?.findRenderObject() != null) {
renderBox = _key.currentContext!.findRenderObject() as RenderBox;
}
final height = renderBox?.size.height;
...
return SomeWidget(
key: _key,
...
)
}
}
Considerations from findRenderObject:
findRenderObject()
will be called every time build()
is called.Upvotes: 3
Reputation: 854
You can wrap in LayoutBuilder:
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
// height: constraints.maxHeight,
// width: constraints.maxWidth
return YourWidget();
}
);
Upvotes: 19