aks*_*hay 6 dart flutter flutter-layout
class TestPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: EdgeInsets.all(10),
child: Container(
width: 300,
color: Colors.orangeAccent,
child: Column(
// mainAxisSize: MainAxisSize.min,
children: [
Text('Hi', style: TextStyle(fontSize: 50)),
],
),
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
我浏览了容器文档,但无法弄清楚为什么会发生这种情况。有人可以解释为什么该列占据其父级的全宽吗?
列占据容器的整个宽度,因为容器强制它这样做。如果您指定 Container 的宽度,那么 Container 基本上将在后台使用 ConstrainedBox,对其子级进行严格约束。在您的情况下,请输入minWidth = 300。
如果您希望 Column 尽可能窄,您应该使用 UnconstrainedBox 小部件包装它,该小部件将接受 Container 自身的严格约束,并使 Column 具有其“自然”大小。如果仍然希望列尽可能高,则需要指定constrainedAxis: UnconstrainedBox 的 Axis.vertical 属性
为了更好地理解Container这里的工作原理,您可以在 flutter 源中找到该小部件的实现:
Container({
Key? key,
this.alignment,
this.padding,
this.color,
this.decoration,
this.foregroundDecoration,
double? width,
double? height,
BoxConstraints? constraints,
this.margin,
this.transform,
this.transformAlignment,
this.child,
this.clipBehavior = Clip.none,
}) : assert(margin == null || margin.isNonNegative),
assert(padding == null || padding.isNonNegative),
assert(decoration == null || decoration.debugAssertIsValid()),
assert(constraints == null || constraints.debugAssertIsValid()),
assert(clipBehavior != null),
assert(decoration != null || clipBehavior == Clip.none),
assert(color == null || decoration == null,
'Cannot provide both a color and a decoration\n'
'To provide both, use "decoration: BoxDecoration(color: color)".',
),
constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints,
super(key: key);
Run Code Online (Sandbox Code Playgroud)
有趣的部分是属性constraints:
constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,如果您为width和/或height属性赋予一个值,它将BoxConstraints对其子部件应用 a ,强制您的子部件Column遵守此约束。
alignment属性如何运作?如果您查看该Container小部件的源代码,您会在其方法中找到它build。
Widget build(BuildContext context) {
Widget? current = child;
// ...
if (alignment != null)
current = Align(alignment: alignment!, child: current);
// ...
}
Run Code Online (Sandbox Code Playgroud)
这意味着通过提供非空alignment属性,您的child小部件将被包装在Align小部件内。现在让我们看一下Align小部件的实现,更准确地说是它的createRenderObject()方法:
@override
RenderPositionedBox createRenderObject(BuildContext context) {
return RenderPositionedBox(
alignment: alignment,
widthFactor: widthFactor,
heightFactor: heightFactor,
textDirection: Directionality.maybeOf(context),
);
}
Run Code Online (Sandbox Code Playgroud)
因此,通过提供一个Align小部件,它将创建一个RenderPositionedBox让我们也通过该方法来看看它的实现performLayout():
@override
void performLayout() {
final BoxConstraints constraints = this.constraints;
final bool shrinkWrapWidth = _widthFactor != null || constraints.maxWidth == double.infinity;
final bool shrinkWrapHeight = _heightFactor != null || constraints.maxHeight == double.infinity;
if (child != null) {
child!.layout(constraints.loosen(), parentUsesSize: true);
size = constraints.constrain(Size(
shrinkWrapWidth ? child!.size.width * (_widthFactor ?? 1.0) : double.infinity,
shrinkWrapHeight ? child!.size.height * (_heightFactor ?? 1.0) : double.infinity,
));
alignChild();
} else {
size = constraints.constrain(Size(
shrinkWrapWidth ? 0.0 : double.infinity,
shrinkWrapHeight ? 0.0 : double.infinity,
));
}
}
Run Code Online (Sandbox Code Playgroud)
在那里,您可以根据其父项的和BoxConstraints来应用一些内容。childmaxWidthmaxHeight
| 归档时间: |
|
| 查看次数: |
6537 次 |
| 最近记录: |