颤动: SizedBox Vs 容器,为什么要用一个而不是另一个?

当我开始思考这两个组成部分时,我发现自己在争论为什么我应该选择其中一个而不是另一个。我想到了一些问题:

  1. 容器和 SizedBox 有什么区别?

  2. 我知道 Container 可以有其他参数,比如填充或装饰,但是如果我不使用这些参数,为什么要使用 SizedBox 而不是 Container?

  3. 他们之间有性能差异吗?

36195 次浏览

Small Update: When used for whitespace, there is now even a linter warning to prefer ABC0 instead of Container. The main advantage seems to be that SizedBox can be const and won't even create a new instance during runtime.


Thanks to the magic of open source, you don't have to guess too much.

Container is basically just a convenience widget which sometimes saves you to nest 4 other widgets. If you pass width/height into the Container:

       constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints,

Which will result in:

    if (constraints != null)
current = ConstrainedBox(constraints: constraints, child: current);

And the ConstrainedBox in effect is pretty much the same as a SizedBox, just more flexible.

A SizedBox will do:

  @override
RenderConstrainedBox createRenderObject(BuildContext context) {
return RenderConstrainedBox(
additionalConstraints: _additionalConstraints,
);
}


BoxConstraints get _additionalConstraints {
return BoxConstraints.tightFor(width: width, height: height);
}

ie. It is effectively the same. If you only use Container for width/height there might be a very minor minor negligible performance overhead. but you most certainly will not be able to measure it.. But I would still recommend SizedBox because it's way clearer. imho.

I'd like to add that SizedBox is not only simpler, but it also can be made const, while Container cannot. This may or may not be something you need.

If you need a box with color you cannot use SizedBox. But https://pub.dev/packages/assorted_layout_widgets has the Box widget, which is something between a SizedBox and a Container: You can have color and it can be made const. Note I am the author of this package.

SizedBox and Container creates a RenderObject. The RenderObject lives in the render tree and some computations are performed on it, even if it paints nothing on the screen.

We can do better, we can have a widget which does not create a RenderObject, while being still valid. The Nil widget is the minimal implementation for this use case. It only creates an Element and does nothing while it's building. Because the optimal way to use it, is to call const Nil(), it also comes with a nil constant that you can use everywhere (which is a const Nil()).

SizedBox() is a widget for giving some constant height or width between two widgets. It does not contain any decorative properties just like color, borderRadius etc.

On the other hand Container() is a widget that any person can modify according to his/her needs.

Just go through properties of both widgets you will see a huge difference between them.