ToB企服应用市场:ToB评测及商务社交产业平台
标题:
Flutter Row 实例 —— 新手礼包
[打印本页]
作者:
饭宝
时间:
2024-8-4 17:23
标题:
Flutter Row 实例 —— 新手礼包
各人好,我是 17。
本文在 3.31 日全站综合热榜第一。
新手礼包一共 3 篇文章,每篇都是形貌只管具体,实例讲解,包会!
Flutter Row 实例 —— 新手礼包
Flutter TextField UI 实例 —— 新手礼包
Flutter TextField 交互实例 —— 新手礼包
本篇先容 Row 的用法,用实例讲解 flex 弹性布局原理。本来在 Flutter 弹性布局的基石: Flex 和 Flexible 一文中的内容已经包含 Row 了,但因为 Row 太常用了,以是单写一篇。
Row 的尺寸
默认情况下, Row 在宽度上只管大,在高度上只要能包住全部的 children 即可。
第一个示例给出全部代码,后面的只给出 Row 的代码。在 Row 的外面加一个 Container ,是为了给 Row 加一个 border,方便查看。减去 margin,padding,border 后 ,Row 的宽度为 300。
MaterialApp(
home: Scaffold(
body: Container(
width: 342,
alignment: Alignment.center,
child: Container(
padding: const EdgeInsets.all(10),
margin: const EdgeInsets.all(10),
decoration:
BoxDecoration(border: Border.all(color: Colors.blue)),
child: Row(
children: [
Container(
width: 100,
height: 50,
color: const Color.fromARGB(255, 82, 143, 222),
),
],
)))));
复制代码
在本例中,Row 的宽度达到答应的最大值 300。高度为 50,正好可以包含蓝色块的高度。MainAxisSize.min 可以让 Row 的宽度也正好能包含 children。
Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 100,
height: 50,
color: const Color.fromARGB(255, 82, 143, 222),
),
],
);
复制代码
mainAxisSize:MainAxisSize.min 让 Row 的宽度紧缩,直到正好包含 全部 children 为止。本例中,正好包含蓝色块,最终宽度为 100。
mainAxisSize 的默认值是 mainAxisSize.max
非弹性布局
非弹性布局是说在 children 中没有 Expanded,Flexible 这种有 flex 参数的 child。
Row(
children: [
Container(
width: 100,
height: 50,
color: const Color.fromARGB(255, 82, 143, 222),
),
const Text(
"IAM17",
style:
TextStyle(color: Color(0xFFC45F84), fontSize: 24),
)
],
);
复制代码
非弹性布局中,Row 的 children 在宽度方面没有限定, child 按本身期望的尺寸在水平方向依次分列。如果 children 的总宽度没有超过 Row 的宽度,没有什么问题。如果超过了 Row 的宽度,在开发情况下,会给出警告。
比如修改 Container 的 width:100 为 width:400,这个时候 Row 已经没有多余的空间给 Text 了,甚是连 Container 也放不下。
在生产情况中,多出来的部分会被直接截断。
弹性布局
弹性布局是说在 children 中有 Expanded,Flexible 这种有 flex 参数的 child。
简单来说,Row 分配空间的过程是这样的。
先分配非弹性 child,比如 Container,Text,这些没有 flex 属性的 Widget。
把剩余的空间按 flex 值的大小,分给全部的弹性块。
如果是用 Expanded 包起来的 child, child 的大小就是 第 2 步分配空间的大小;如果是用 Flexible 包起来,child 的大小可以从 0 到 第 2 步分配空间的大小 之间自行决定。
这里说的 Flexible 的 fit 参数的值为 FlexFit.loose。Expanded 就是 fit 参数为 FlexFit.tight 的 Flexible。
让 child 占用全部分配到的空间,用 Expanded 包起来
Row(
children: [
Expanded(
child: Container(
width: 100,
height: 50,
color: const Color.fromARGB(255, 82, 143, 222),
)),
const Text(
"IAM17",
style:
TextStyle(color: Color(0xFFC45F84), fontSize: 24),
)
],
)
复制代码
Row 的宽度为 300,先给非弹性块 Text 分配固定大小空间,剩余的全分给的 Expanded。child 蓝色块占用全部 Expanded 分配到的空间。
我们注意到 Container 的 width 是 100,实际上,就算是这里写 0,或写 1000 都没有关系,用 Expanded 包起来的 child 的 width 属性会被忽略。
Expanded 包起来的 child 的 width 是不能自定义的,如果 child 要自定义 width 又要保持弹性布局怎么办?用 Flexible!
让 child 可以在分配到的空间内自行决定大小,用 Flexible 包起来。
在下面的例子中 Row 总的可用宽度为 300,两个 Container 各占 100,还余 100 空缺在两个 Container 之间
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 100,
height: 50,
color: Colors.blue,
),
Container(
width: 100,
height: 50,
color: Colors.red,
),
],
)
复制代码
如今我们把第一个 container 用 Flexible 包起来。
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Container(
width: 100,
height: 50,
color: Colors.blue,
)),
Container(
width: 100,
height: 50,
color: Colors.red,
),
],
)
复制代码
重新执行查看效果,发现没什么变化。这是因为 总宽度为 300,分给非弹性赤色块 100后另有 200, 唯一的弹性块拿到 200。蓝色块的 100 在分配到的空间范围内,以是没有什么反应。
把第一个 Container 的 width 加大到 150 查看效果,发现第一个 Container 的宽度变为 150 了。同理 150 也在 分配到的 200 之内。
继续加大 width 的宽度到 200,发现他们已经紧贴到一起了。继续加大就没有任何效果了,但也不会报错。
继续加大到 200 以上就超太过配到的 200了,以是宽度不再增加。不会报错是因为蓝色块被 Flexible 限定在 200 以内,加上赤色块的总宽度在 300 以内,没有超出,当然不会报错。
如果左面 Container 的 宽度不是我们指定的,而是 Container 的 child 撑起来的,那么就可以实现宽度自适应的布局效果,不消担心会超出边界。
Flexible 的 flex 与 fit 参数
Flexible 的 flex 决定了可以分配多少剩余空间。fit 参数决定 child 可否自行决定大小。
看下面的的例子,赤色块为固定宽度,绿蓝为弹性宽度。在fit: FlexFit.tight 的情况下,绿色块和赤色块的 width 无效。因为 Flexible 的 flex 已经决定了宽度值,child 只能用这个值不能修改。
Row(children: [
Container(
width: 20, height: 50, color: Colors.red),
Flexible(
fit: FlexFit.tight,
flex: 1,
child: Container(
width: 100, height: 50, color: Colors.green)),
Flexible(
fit: FlexFit.tight,
flex: 2,
child: Container(
width: 100, height: 50, color: Colors.blue))
]
复制代码
本例中 Row 的宽度为 320,起首分配 20 给固定宽度的赤色块,剩余的 300 由两个弹性块瓜分。根据 flex 值,绿色块得到 100,蓝色块得到 200。Flex 值越大,得到的空间越大。
fit: FlexFit.tight 的 Flexible ,一般是用 Expanded。
在fit: FlexFit.loose 的情况下,绿色块和赤色块的 width 是有作用的,可以在 0 和最大值之间自定义本身的宽度。
我们把第二个 Flexible 的 fit: FlexFit.tight 修改为 fit: FlexFit.loose,蓝色块的 width 起作用了,表现为 100 宽。
我们调整一下摆放方式,蓝色块省出来的 100 空间被填充到各个块之间了。
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
...
复制代码
在 children 之间加空缺。
在 children 之间增加固定空缺用 SizedBox
我们发现 Container 和 文本紧挨在一起了,想要他们之间有一个距离。可以用 Padding 把 Container 或 Text 包起来,但是这样写起来比较麻烦,而且多了一个层级,也不美观,不如用 SizedBox。
Row(
children: [
Container(
width: 100,
height: 50,
color: const Color.fromARGB(255, 82, 143, 222),
),
const SizedBox(width: 20,),
const Text(
"IAM17",
style:
TextStyle(color: Color(0xFFC45F84), fontSize: 24),
)
],
)
复制代码
在 children 之间增加弹性空缺用 Spacer
Row(
children: [
Container(
width: 100,
height: 50,
color: const Color.fromARGB(255, 82, 143, 222),
),
const Spacer(),
const Text(
"IAM17",
style:
TextStyle(color: Color(0xFFC45F84), fontSize: 24),
)
],
)
复制代码
文本 “IAM17” 与 蓝色块 之间的空缺是 文本 “IAM17” 与 文本 “Flutter” 之间空缺宽度的两倍。Row 的宽度如果增加或缩小,空缺的宽度也会增加会缩小,但会保持两倍的关系。
平均分配空缺
平均分配空缺用 mainAxisAlignment 参数,具体用法详见 Flutter Wrap 图例。虽然讲的是 Wrap Widget,但是 alignment 与 Row 的 mainAxisAlignment 用法是一样的。比如两端对齐:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
...
复制代码
Row 嵌套
Row 嵌套的时候需要注意下,因为一不小心会报错。
Row(
children: [
Row(children: [
Expanded(
child: Container(
width: 100,
height: 50,
color: Color.fromARGB(255, 210, 74, 137),
))
]),
],
)
复制代码
Expanded 是要占据全部的可用空间,内层的 Row 在宽度可以是无穷,Expanded 无法占据无穷空间,以是报错。解决的办法很简单,让 内层的 Row 的宽度有限就可以了。
Row(
children: [
Expanded(
child: Row(children: [
Expanded(
child: Container(
width: 100,
height: 50,
color: Color.fromARGB(255, 210, 74, 137),
))
])),
],
)
复制代码
或者给 Row 加一个宽度束缚。比如用 SizedBox 包起来。
Row(
children: [
SizedBox(
width: 150,
child: Row(children: [
Expanded(
child: Container(
width: 100,
height: 50,
color: Color.fromARGB(255, 210, 74, 137),
))
])),
],
);
复制代码
用 Flexible 包起来也是可以的,Flexible 与 Expanded 的区别在于 Flexible 给 child loose 束缚,Expanded 给 child tight 束缚。通俗一点的说法是 Flexible 的 child 的宽度可以从 0 到 最大值之间本身决定。Expanded 的 child 的宽度只能是固定值,不能修改。
Row 嵌套的时候报错本质上是因为宽度无穷,遇到别的宽度无穷的场景也会出现这样的问题,比如 ListView 横向滚动的时候,把 Row 嵌套在 ListView 中也会有类似的问题。
ListView(
scrollDirection: Axis.horizontal,
children: [
Row(children: [
Expanded(
child: Container(
width: 100,
height: 50,
color: Color.fromARGB(255, 210, 74, 137),
))
]),
],
)
复制代码
解决办法相同,也是把 Row 用 Flexible 或 Expanded 包起来,或加一个宽度束缚。
ListView(
scrollDirection: Axis.horizontal,
children: [
Expanded(
child: Row(children: [
Expanded(
child: Container(
width: 100,
height: 50,
color: Color.fromARGB(255, 210, 74, 137),
))
])),
],
);
复制代码
到这里 Flutter Row 的常用的用法就都先容完了。谢谢观看!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4