Flutter —— 弹性盒子布局
1.布局
1.1 Row & Column & Stack
Row可以沿水平方向排列其子widget,也就是横向布局。Column可以在垂直方向排列其子组件,可以理解为纵向布局。而Stack允许子组件堆叠,是层叠布局,可以理解为Z轴。
1.2 Alignment
class LayoutDemo extends StatelessWidget {
const LayoutDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
alignment: const Alignment(0,0),
child: Row(
children: [
Icon(Icons.add,size: 30,),
Icon(Icons.ac_unit,size: 60,),
Icon(Icons.baby_changing_station,size: 90,),
],
),
);
}
}
运行后得到下面的图,这里发现x对row没有影响了,因为container有多宽,row就有多宽,所以X对row就没有影响了。从这里也可以推出Y对Column没有影响,而Stack则是都有影响。
return Container(
color: Colors.yellow,
alignment: const Alignment(0, 0),
child: Column(
children: [
Container(
color: Colors.red,
child: Icon(
Icons.add,
size: 90,
),
),
Container(
color: Colors.blue,
child: Icon(
Icons.ac_unit,
size: 60,
),
),
Container(
color: Colors.white,
child: Icon(
Icons.baby_changing_station,
size: 30,
),
),
],
),
);
运行后发现确实Y对Column没有影响。
下面是Stack的情况,看到确实都有影响。
1.3 主轴
在row中,主轴是X轴,默认朝右,在Column中,主轴是Y轴,默认朝下,主轴对齐属性主要有:start,end,center,spaceBetween,spaceAround,spaceEvenly。使用text Direction的话 可以改变主轴的方向。
Start就是正常的左对齐,这里就不测试了。
给Row的mainAxisAlignment赋值为MainAxisAlignment.end。
mainAxisAlignment: MainAxisAlignment.end,
运行后得到下图,发现向右对齐了。
给Row的mainAxisAlignment赋值为MainAxisAlignment.center。
给Row的mainAxisAlignment赋值为MainAxisAlignment.spaceBetween。
给Row的mainAxisAlignment赋值为MainAxisAlignment.spaceBetween,这里是将剩余的空间平均分布到控件之间。
给Row的mainAxisAlignment赋值为MainAxisAlignment.spaceAround,这里是将剩余的空间平均分布到小控件周围。
给Row的mainAxisAlignment赋值为MainAxisAlignment.spaceEvenly。这里是将剩余的空间和小部件平均分。
1.4 交叉轴
交叉轴就是垂直与主轴方向的轴。
将Row里面的crossAxisAlignment设为CrossAxisAlignment.start,可以看到三个icon的头部是对齐的。
将Row里面的crossAxisAlignment设为CrossAxisAlignment.end,可以看到三个icon的底部是对齐的。
将Row里面的crossAxisAlignment设为CrossAxisAlignment.center,可以看到三个icon的中心是对齐的。
CrossAxisAlignment.baseline,需要搭配textBaseline使用,否则会报错。将icons改成文字来看效果。发现这个是文字的底部对齐了。
1.5 Expanded
Expanded 只能作为 Flex 的孩子(否则会报错),它可以按比例“扩伸”Flex子组件所占用的空间。因为 Row和Column 继都承自Flex,所以 Expanded 也可以作为它们的孩子。所有的Expanded按照其 flex 的比例来分割主轴的全部空闲空间。 将Row的children里面的Container用Expanded包起来。
return Container(
color: Colors.yellow,
alignment: const Alignment(0, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Expanded(
child: Container(
color: Colors.red,
child: Text(
'你好',
style: TextStyle(fontSize: 20),
),
),
),
Expanded(
child: Container(
color: Colors.blue,
child: Text(
'女吼',
style: TextStyle(fontSize: 40),
),
),
),
Expanded(
child: Container(
color: Colors.white,
child: Text(
'类猴',
style: TextStyle(fontSize: 60),
),
),
),
],
),
);
运行后看到三个文本平分了row的主轴。如果空间不够用则会自动换行。在Expanded里面,主轴方向设置大小将没有意义,也就是说,在Row里面设置width不会生效,在column里面设置height不会生效。
4. 总结
- 布局部件
- Center。让子部件在本部件的居中位置显示
- Container中相对位置属性
- Alignment。参数:x 和 y
- 原点在中间位置
- Row&Column
- 横向布局Row。
- 子部件按照主轴方向(横向)排列。主轴方向从左到右
- 纵向布局Column。
- 子部件按照主轴方向(纵向)排列。主轴方向从上到下
- 每一个UI部件都可以看成一个矩形的“盒子”
- 每一个盒子都有外边距Margin和内边距padding.
- 主轴:MainAxisAlignment
- spaceBetween: 剩下的空间平均分布到小部件之间!!
- spaceAround: 剩下的空间平均分布到小部件周围!!
- spaceEvenly:剩下的空间和小部件一起平均分!!
- start 向主轴开始的方向对齐。
- end 向主轴结束的方向对齐。
- center 主轴方向居中对齐。
- 交叉轴:CrossAxisAlignment 垂直于主轴方向
- baseline:文字底部对齐
- center:交叉轴方向居中对齐。
- end:向交叉轴结束的方向对齐。;
- start:向交叉轴开始的方向对齐;
- stretch:填满交叉轴方向;
- 横向布局Row。
- Expanded 填充布局
- 在主轴方向不会剩下间隙。将被Expanded包装的部件进行拉伸和压缩
- 主轴横向,宽度设置没有意义
- 主轴纵向,高度设置没有意义
- 当Text被Expanded包装后,文字可以自动换行。这也被称作灵活布局。
转载自:https://juejin.cn/post/7026914845245063182