import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: TestCode(),
);
}
}
class TestCode extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 200,
height: 100,
color: Colors.red,
child: Container(
width: 100,
height: 100,
color: Colors.green,
),
);
}
}
实际上,这段代码非常简单。我只想显示一个200 * 100的红色立方体和一个100 * 100的绿色立方体。
但是运行效果是全屏绿色?为什么会这样?
接下来,我在Scaffold
上添加了TestCode
,如下所示
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(body: TestCode()),
);
}
效果似乎再次接近,显示出200 * 100的绿色长方体?为什么会这样?
接下来,我将对齐方式添加到第一个Container中,如下所示
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.topLeft,
width: 200,
height: 100,
color: Colors.red,
child: Container(
width: 100,
height: 100,
color: Colors.green,
),
);
}
最后达到了预期的效果,为什么会这样,谁能解释,我必须弄清楚。
答案 0 :(得分:0)
height
和width
属性将被覆盖。您可以在本文上获得有关框约束的更多信息:
Dealing with box constraints
Flutter有layout widgets一堆可以完成工作。在您的情况下,您将Container
赋予了home
的{{1}}属性。这会将MaterialApp
的最小尺寸设置为屏幕尺寸。 Container
希望他的孩子填满整个屏幕,以防止出现黑色像素。这是预期的行为。但是,您可以使用可以打破此约束的布局小部件,它可以是MaterialApp
,Center
或其他。
FittedBox
的示例:
FittedBox
输出:
答案 1 :(得分:0)
只需将您的代码更改为此。您必须指定对齐方式。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: TestCode(),
);
}
}
class TestCode extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 200.0,
height: 100.0,
color: Colors.red,
alignment: Alignment.center, // where to position the child
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green,
),
);
}
}
答案 2 :(得分:0)
这是由我们在Flutter中所谓的“严格约束与宽松约束”引起的。
TD; DR,宽度/高度是严格的约束(在某种意义上,只有一种可能性)。
但是您从未向框架指定如何在父级指定的200x200的严格约束与子级100x100的严格约束之间进行切换。
这会导致约束冲突。这两个小部件都有一种可能性,没有任何一种可以使它们一起生活(像alignment
)。
在这种情况下,父级的约束总会赢,因此我们最终得到一个200x200的正方形,子级填充了父级。
如果那不是您想要的东西,那么您应该将“紧”约束转换为“松”约束。
宽松约束是为孩子提供多种可能性的约束,通常可以消除冲突。
引入宽松约束的最常见方法是使用Alignment
(或Center
或alignment
的{{1}}属性)。
这样,如果您写:
Container
然后在这种情况下,Container(
width: 200,
height: 100,
color: Colors.red,
child: Center(
child: Container(
width: 100,
height: 100,
color: Colors.green,
),
),
);
将充当父母与孩子Center
之间的中间地带。
它将理解,两者都想要不同的大小。它将通过使孩子与父母对齐来解决冲突。
现在,您可能会问为什么要这样做?为什么Flutter不能在此处隐式添加路线?
那是因为在许多情况下,这种行为是所希望的。
基本上,这可以确保始终有一种自定义对象大小的方法(而不必在所有小部件上公开大量属性)。
以Container
为例。它不会暴露任何改变其大小的内容,但我们可能希望它充满整个屏幕。
在这种情况下,我们会写:
RaisedButton
由于我们先前说明的行为,即在发生冲突时父级会覆盖子级大小,因此此代码将产生一个SizedBox.expand(
child: RaisedButton(...),
)
,可以正确填充屏幕。
答案 3 :(得分:0)
请始终记住,默认情况下,容器采用父级的尺寸,这是将所有元素/小部件包装在根顶级容器中的一种好习惯,然后将每个容器包装在带有定位所需部件的小部件树中容器(中心可以是这样的小部件) 解决您的问题的简单方法是:
// The root container
Container(
//Center for positioning the child Container properly
child: Center(
child: Container(
height: 100,
width: 200,
color: Colors.red,
//Center for positioning the child Container properly
child: Center(
child: Container(
height: 100,
width: 100,
color: Colors.green,
),
),
),
),
),