The provided content discusses methods for obtaining the size and position of widgets in a Flutter application, emphasizing the necessity of a RenderBox object associated with a widget's context and the use of GlobalKey to access this information, as well as addressing common issues and solutions when trying to retrieve these properties during the widget lifecycle.
Abstract
Understanding how to retrieve the dimensions and on-screen position of widgets is crucial for Flutter developers working on UI layout and design. The article explains that widgets themselves do not inherently possess size or position, and it is necessary to interact with the RenderBox associated with the widget's build context to obtain this data. The author demonstrates this through a demo app with colored panels, using GlobalKey to assign a unique identifier to a widget and then accessing its RenderBox to find out its size and position. The article also addresses the challenge of querying these properties at the wrong time in the widget lifecycle, such as within the constructor or initState, which can lead to errors as the rendering information is not yet available. The solution proposed involves using WidgetsBinding.instance.addPostFrameCallback to defer the retrieval of size and position until after the first frame has been rendered, ensuring that the layout information is accessible and preventing null reference errors.
Opinions
The author suggests that obtaining widget size and position is a common requirement and can be straightforward once understood.
There is an emphasis on the importance of reading Flutter's documentation to grasp concepts that may initially seem complex but are actually simple.
The author provides a practical example and code snippets to illustrate the process, indicating a preference for hands-on learning and demonstration.
The article acknowledges potential confusion and pitfalls for developers, particularly when trying to access rendering information too early in the widget lifecycle.
A recommendation is made for an external package called after_layout, created by Simon Lightfoot, as an additional tool for developers to handle post-layout operations, suggesting a collaborative and resource-sharing approach within the Flutter community.
The author expresses enthusiasm and encouragement for continuous learning in Flutter development, highlighting that everyday brings new knowledge and opportunities to improve.
Flutter : Widget Size and Position
I have read many questions about how we can obtain the dimensions or positions of the widgets that we have on screen.
In some cases we find ourselves in situations in which we want to achieve that for any reason.
The widget doesn’t have position or size by itself, in order to achieve this it’s necessary that we obtain the RenderBox associated with the context of our Widget.
But how do we do this?
Let’s start building a demo app which has 3 panels of different colors, Red, Purple and Green inside a Column and we have two buttons at the bottom to get the Size and Position.
This is the code of the demo app:
And the result:
Ok so now the question is : How can I get the size and position of each panel?
Let’s focus on just one panel for this post (Red panel) , after we know how to get the size and position for one panel it should be easy for the others.
Get the size of a Widget
In order to do that, we need our Widget to have a Key, for this we create a GlobalKey and assign it to our Widget.
Once our Widget already has a Key, we can use this Key to be able to obtain the size in the following way:
_getSizes() {
final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject();
final sizeRed = renderBoxRed.size;
print("SIZE of Red: $sizeRed");
}
If we press the Get Sizes button, you’ll get this result in the console:
flutter: SIZE of Red: Size(375.0, 152.9)
now we know that our Red panel has 375.0 as width and 152.9 as height
It was easy, right?
Let’s go to obtain the position in which our Widget is located.
Get the position of a Widget
In the same way that we did previously, our Widget must have an associated Key.
Now we update the method to obtain the position of the Widget relative to the top-left of the defined position (in this case we are using 0.0 it means the top-left corner of our current screen).
_getPositions() {
final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject();
final positionRed = renderBoxRed.localToGlobal(Offset.zero);
print("POSITION of Red: $positionRed ");
}
If we press the Get Positions button, you’ll get this result in the console:
flutter: POSITION of Red: Offset(0.0, 76.0)
It means our Widget start from 0.0 from the X axis and 76.0 from the Y axis from TOP-LEFT.
Why 76.0? That’s because there is an AppBar above that has a height of 76.0.
So we already know how to get the size and position of our Widgets, well so far. Yay!!
But what happens if I’m interested in getting the size or position at the beginning, without having to press a button for it.
Ok then let’s call our methods in our constructor.
flutter: The following NoSuchMethodError was thrown building Builder:
flutter: The method 'findRenderObject' wascalledonnull.
flutter: Receiver: null
flutter: Tried calling: findRenderObject()
Ok let’s try calling the methods from the initState , it should work ….. or no
Many times, we get complicated by things that are very simple, it is necessary to read the documentation that Flutter provides, anyway every day we learn new things.