镇楼图!!!
gogogo。
一、Row 和 Column
都是容器
Row是横向布局
Column 是竖向布局
Row横横横,Column竖竖竖
开打了喂
二、Row和Column的属性
一、Row和Column的属性
- children:一个包含多个widgets的列表,这些widgets按照Row或Column的布局方向进行布局。
- mainAxisAlignment:此属性决定了如何在主轴上对齐children。
- crossAxisAlignment:这个属性决定了如何在交叉轴上对齐children。
- mainAxisSize:此属性用于确定Row或Column应占用多少主轴空间。
- verticalDirection:对于Column来说,这个属性决定了列的开始位置是在顶部还是在底部。
- textDirection:这个属性确定了Row或Column的children的排列方向。
- textBaseline:当crossAxisAlignment设置为CrossAxisAlignment.baseline时,这个属性定义了如何测量距离基线的距离。
让我们通过几个具体的代码示例,来更好地理解这些属性。
三、属性详解
使用mainAxisAlignment和crossAxisAlignment
mainAxisAlignment和crossAxisAlignment定义了子组件在主轴和交叉轴上的对齐方式。让我们通过几个具体的示例来看看如何使用这两个属性。
例子1:
例子1:Row的主轴和交叉轴对齐方式
// 例子1:Row的主轴和交叉轴对齐方式
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Example'),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.star, size: 50), // 星形图标1
Icon(Icons.star, size: 50), // 星形图标2
Icon(Icons.star, size: 50), // 星形图标3
],
),
),
),
);
}
}
在这个例子中,我们有一个Row,其中包含三个大小为50的星形图标。
mainAxisAlignment
设置为MainAxisAlignment.spaceAround
,意味着Row会在每个星形图标之间以及两边均匀地分配空间
。
crossAxisAlignment
设置为CrossAxisAlignment.center
,所以这些图标会在Row的中心进行垂直对齐
。
例子2:
// 例子2:Column的主轴和交叉轴对齐方式
// 例子2:Column的主轴和交叉轴对齐方式
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(Icons.star, size: 50), // 星形图标1
Icon(Icons.star, size: 50), // 星形图标2
Icon(Icons.star, size: 50), // 星形图标3
],
)
这个例子中,我们有一个Column,其中包含三个大小为50的星形图标。mainAxisAlignment设置为MainAxisAlignment.spaceBetween,意味着Column会在每个星形图标之间均匀地分配空间,但不在两边分配空间。crossAxisAlignment设置为CrossAxisAlignment.start,所以这些图标会从Column的开始位置(默认为顶部)开始对齐。
Row和Column主轴、纵轴上的属性区别
对于mainAxisAlignment
和crossAxisAlignment
在Row
和Column
上的效果
对齐方式 | Row的效果 | Column的效果 |
---|---|---|
MainAxisAlignment.start | 子组件在行的开始端排列 | 子组件在列的开始端排列 |
MainAxisAlignment.end | 子组件在行的结束端排列 | 子组件在列的结束端排列 |
MainAxisAlignment.center | 子组件在行中间排列 | 子组件在列中间排列 |
MainAxisAlignment.spaceBetween | 子组件在行两端对齐,之间等距排列 | 子组件在列两端对齐,之间等距排列 |
MainAxisAlignment.spaceAround | 子组件在行中等距排列,两端间隔半倍 | 子组件在列中等距排列,两端间隔半倍 |
MainAxisAlignment.spaceEvenly | 子组件在行中等距排列,两端间隔一倍 | 子组件在列中等距排列,两端间隔一倍 |
CrossAxisAlignment.start | 子组件在交叉轴的开始端对齐 | 子组件在交叉轴的开始端对齐 |
CrossAxisAlignment.end | 子组件在交叉轴的结束端对齐 | 子组件在交叉轴的结束端对齐 |
CrossAxisAlignment.center | 子组件在交叉轴的中间对齐 | 子组件在交叉轴的中间对齐 |
CrossAxisAlignment.stretch | 子组件在交叉轴上拉伸以填充空间 | 子组件在交叉轴上拉伸以填充空间 |
CrossAxisAlignment.baseline | 子组件的基线对齐 | 子组件的基线对齐 |
下面是可以直接运行的代码,它会演示以上每种对齐方式的效果:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
String describeEnum(Object enumEntry) {
final String description = enumEntry.toString();
final int indexOfDot = description.indexOf('.');
assert(indexOfDot != -1 && indexOfDot < description.length - 1);
return description.substring(indexOfDot + 1);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Alignments'),
),
body: ListView(
children: <Widget>[
for (MainAxisAlignment alignment in MainAxisAlignment.values)
Column(
children: [
Text('MainAxisAlignment.${describeEnum(alignment)}', style: TextStyle(fontSize: 20)),
Container(
height: 50,
child: Row(
mainAxisAlignment: alignment,
children: [
Container(color: Colors.red, width: 50, height: 50),
Container(color: Colors.green, width: 50, height: 50),
Container(color: Colors.blue, width: 50, height: 50),
],
),
),
Divider(),
],
),
for (CrossAxisAlignment alignment in CrossAxisAlignment.values)
if (alignment != CrossAxisAlignment.baseline)
Column(
children: [
Text('CrossAxisAlignment.${describeEnum(alignment)}', style: TextStyle(fontSize: 20)),
Container(
height: 100,
child: Row(
crossAxisAlignment: alignment,
children: [
Container(color: Colors.red, width: 50, height: 30),
Container(color: Colors.green, width: 50, height: 50),
Container(color: Colors.blue, width: 50, height: 70),
],
),
),
Divider(),
],
),
],
),
),
);
}
}
Row和Column各种对齐效果
看效果看效果
使用mainAxisSize
mainAxisSize定义了Row或Column应占用多少主轴空间。让我们通过一个具体的示例来看看如何使用这个属性。
例子3:
// 例子3:Row的mainAxisSize
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.star, size: 50), // 星形图标1
Icon(Icons.star, size: 50), // 星形图标2
],
)
在这个例子中,我们有一个Row,其中包含两个大小为50的星形图标。mainAxisSize设置为MainAxisSize.min,意味着Row的宽度将尽可能小,正好容纳其所有子组件。
使用verticalDirection
verticalDirection
属性确定列的开始位置是在顶部还是在底部。让我们通过一个例子来看看这个属性的作用。
例子4:
// 例子4:Column的verticalDirection
Column(
verticalDirection: VerticalDirection.up,
children: <Widget>[
Text('Hello', style: TextStyle(fontSize: 20)), // 文字1
Text('Flutter', style: TextStyle(fontSize: 20)), // 文字2
],
)
在这个例子中,我们有一个Column,其中包含两段文字。verticalDirection
设置为VerticalDirection.up
,意味着第一个子组件将位于底部,后续的子组件将位于其上方。
使用textDirection
textDirection
属性确定了Row或Column的children的排列方向。这个属性特别重要,特别是当你需要支持从右到左(RTL)语言时。
例子5:
// 例子5:Row的textDirection
Row(
textDirection: TextDirection.rtl,
children: <Widget>[
Text('Hello', style: TextStyle(fontSize: 20)), // 文字1
Text('Flutter', style: TextStyle(fontSize: 20)), // 文字2
],
)
在这个例子中,我们有一个Row,其中包含两段文字。textDirection
设置为TextDirection.rtl
,所以第一个子组件将位于右侧,后续的子组件将位于其左侧。
使用textBaseline
textBaseline
属性定义了当crossAxisAlignment
设置为CrossAxisAlignment.baseline
时,如何测量距离基线的距离。这个属性常常与文字对齐有关。
例子6:
// 例子6:Row的textBaseline
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: <Widget>[
Text('Hello', style: TextStyle(fontSize: 20)), // 文字1
Text('Flutter', style: TextStyle(fontSize: 40)), // 文字2
],
)
在这个例子中,我们有一个Row,其中包含两段不同字体大小的文字。crossAxisAlignment
设置为CrossAxisAlignment.baseline
,textBaseline
设置为TextBaseline.alphabetic
,所以无论字体大小如何,所有的文字都会沿着其字母的基线对齐。
emm,我想,已经,很详细了。