Flutter 的 Row 组件用于在水平方向排列子组件,是构建灵活布局的核心组件之一。它的用法其实和Column基本一致,只是一个纵向列表布局,一个横向列表布局。
以下是 通过一些Row 的用法示例,包含核心属性及常见场景的解决方案。
一、基本用法
Row 的基本结构如下:
Container(
height: 200,
width: 300,
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2)
),
child: Row(
children: [
Container(width: 50, color: Colors.red),
Container(width: 50, color: Colors.green),
Container(width: 50, color: Colors.blue),
Container(width: 50, color: Colors.black),
],
),
),
二、核心属性
1. 主轴对齐:mainAxisAlignment
控制子组件在水平方向(主轴)的对齐方式,默认为 MainAxisAlignment.start(从左侧开始排列)。
可选值:
mainAxisAlignment.start:左对齐
mainAxisAlignment.end:右对齐
mainAxisAlignment.center:居中对齐
mainAxisAlignment.spaceBetween:均匀分布(首尾无空隙)
mainAxisAlignment.spaceAround:均匀分布(子组件两侧空隙相等)
mainAxisAlignment.spaceEvenly:完全均匀分布
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(width: 50, color: Colors.red),
Container(width: 50, color: Colors.green),
Container(width: 50, color: Colors.blue),
Container(width: 50, color: Colors.black),
],
),
2. 交叉轴对齐:crossAxisAlignment
控制子组件在垂直方向(交叉轴)的对齐方式,默认为 CrossAxisAlignment.center。
可选值:
CrossAxisAlignment.start:顶部对齐
CrossAxisAlignment.end:底部对齐
CrossAxisAlignment.center:垂直居中
CrossAxisAlignment.stretch:拉伸子组件高度(需子组件允许)
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(width: 50, height: 100, color: Colors.red),
Container(width: 50, height: 100, color: Colors.green),
Container(width: 50, height: 100, color: Colors.blue),
Container(width: 50, height: 100, color: Colors.black),
],
),
3. 主轴尺寸:mainAxisSize
控制 Row 自身在主轴方向的占用空间:
MainAxisSize.max(默认):占满父容器的宽度MainAxisSize.min:根据子组件总宽度自适应
Container(
height: 200,
width: 300,
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2)
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(width: 50, height: 100, color: Colors.red),
Container(width: 50, height: 100, color: Colors.green),
Container(width: 50, height: 100, color: Colors.blue),
Container(width: 50, height: 100, color: Colors.black),
],
),
),
说明: 这个属性主要是控制Row的宽度,设置max,则Row的宽度会尽可能的大,和父组件有一样大,如果设置min,则Row只会包裹子组件的大小。
4. 文本方向:textDirection
控制子组件的排列方向(从左到右或从右到左):
Row(
textDirection: TextDirection.rtl, // 从右到左排列
children: [Text("A"), Text("B")],
)
5. 垂直方向:verticalDirection
控制子组件在交叉轴的排列方向(默认 VerticalDirection.down,从上到下):
Row(
verticalDirection: VerticalDirection.up, // 从下到上排列
children: [Container(height: 50), Container(height: 100)],
)
三、动态空间分配(Expanded与Flexible)
当需要子组件按比例分配剩余空间时,使用 Expanded 或 Flexible。
1. Expanded
强制子组件填满剩余空间,通过 flex 设置权重(默认1):
Row(
children: [
Expanded(flex: 2, child: Container(color: Colors.red)),
Expanded(flex: 1, child: Container(color: Colors.blue)),
],
)
上述代码中,红色容器占2/3宽度,蓝色占1/3。
2. Flexible
与 Expanded 类似,但允许子组件不填满剩余空间(通过 fit 属性控制):
Row(
children: [
Flexible(fit: FlexFit.loose, child: Container(width: 100)),
Expanded(child: Container(color: Colors.green)),
],
)
四、处理溢出问题
当子组件总宽度超过屏幕宽度时,Row 会抛出溢出错误(如 Right Overflowed by 42 pixels)。
解决方案
- 方案1:使用
SingleChildScrollView包裹Row,实现水平滚动:
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(children: [/* 长内容 */]),
)
- 方案2:用
ListView替代Row:
ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (_, i) => ItemWidget(),
separatorBuilder: (_, __) => SizedBox(width: 10),
itemCount: 10,
)
- 方案3:通过
Expanded或Flexible限制子组件宽度比例。
五、常见布局示例
示例1:图标与文本居中排列
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.access_time),
SizedBox(width: 8),
Text("时间"),
],
)
示例2:按钮组右对齐
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(onPressed: () {}, child: Text("取消")),
SizedBox(width: 10),
ElevatedButton(onPressed: () {}, child: Text("确定")),
],
)
示例3:自适应三栏布局
Row(
children: [
Expanded(flex: 1, child: Sidebar()),
Expanded(flex: 3, child: Content()),
Expanded(flex: 1, child: Ads()),
],
)
六、注意事项
- 避免直接嵌套无约束组件:如
Text或Image可能导致溢出,应包裹Expanded或Container。 - 优先使用
Expanded:需要动态分配空间时,优先选择Expanded而非固定宽度。 - 处理长内容:横向内容过长时,务必使用可滚动组件(如
ListView)。
通过灵活调整 mainAxisAlignment、crossAxisAlignment 和子组件的尺寸,可以快速实现复杂的横向布局结构。若需滚动,务必结合可滚动组件(如 SingleChildScrollView)使用。