Reputation: 844
In the code below, a row of two 300x300 boxes (_Box
) wrapped with FittedBox
shrinks to fit in the screen. As a result, each box becomes smaller than 300x300.
However, if I get the width of a box in the build()
method of _Box
using RenderBox.size
and LayoutBuilder()
, the obtained size is 300.0
and Infinity
respectively.
How can I get the actual displayed size?
I'd like to get it inside the _Box
class, without it getting passed from the parent.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: FittedBox(
child: Row(
children: <Widget>[
_Box(Colors.red),
_Box(Colors.orange),
],
),
),
),
),
);
}
}
class _Box extends StatelessWidget {
const _Box(this.color);
final Color color;
@override
Widget build(BuildContext context) {
RenderBox renderBox = context.findRenderObject();
print(renderBox?.size?.width); // 300.0
return LayoutBuilder(
builder: (_, constraints) {
print(constraints.maxWidth); // Infinity
return Container(
width: 300,
height: 300,
color: color,
);
},
);
}
}
Upvotes: 1
Views: 833
Reputation: 844
I'll answer my own question, although it is not a direct answer.
I couldn't find a way to get the size shrinked by FittedBox
, but I realised that I was able to get around it by using Flexible
instead.
SafeArea(
child: Row(
children: const [
Flexible(
child: _Box(Colors.red),
),
Flexible(
child: _Box(Colors.orange),
),
],
),
);
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 300.0),
child: AspectRatio(
aspectRatio: 1.0,
child: ColoredBox(color: color),
),
);
}
It still seems impossible to get the size via RenderBox
, and it is now possible with LayoutBuilder
. But either way, I didn't need them.
The constraints of the two boxies are shrinked by Flexible
if a smaller space is available, but they expand as big as the space allows, so I limited the maximum size using ConstrainedBox
and AspectRatio
.
I didn't have to stick to FittedBox
. I think I was obsessed with the idea of using it and couldn't think of other solutions when I posted the question two years ago.
Upvotes: 0
Reputation: 185
The Flutter constraints
object is used to limit how large or small a widget can be rendered, and is usually never really used to get the current size of the widget.
The renderBox.size
object is of Size
class, and as a result it has both renderBox.size.width
and renderBox.size.height
as defined getters. Note that these values can only be set once the layout phase of the current view is over: see the findRenderObject()
docs page.
This means that you will have to avoid calling findRenderObject()
from the build()
method. Instead you will have to define a callback function that must execute after the layout process is complete. You can do this using that have widgets that have callback functions like onTap
or onSelected
. How you implement this and finally get the actual layout size by running the callback function is totally dependent on your use case.
Further recommended reading:
Overlay
widget)Upvotes: 1