赞
踩
Row 是一个可以沿水平方向展示它的子组件的组件。
它还可以灵活布局,如果要让某个子组件填充满剩余剩余空间,请使用 Expanded 组件包裹该组件即可。
Row 组件是不可以滚动的,所以在 Row 组件中一般不会放置过多子组件,如果需要滚动的话应该考虑使用 ListView。
如果需要垂直展示,应该考虑 Column 组件。
如果只有一个子组件的话,应该考虑使用使用 Align 或者 Container 组件来定位这个子组件。
说了这么多,对我来说,Row 就是一个 orientation 为 horizontal 的 LinearLayout。
Row({Key key, MainAxisAlignment mainAxisAlignment: MainAxisAlignment.start, MainAxisSize mainAxisSize: MainAxisSize.max, CrossAxisAlignment crossAxisAlignment: CrossAxisAlignment.center, TextDirection textDirection, VerticalDirection verticalDirection: VerticalDirection.down, TextBaseline textBaseline, List<Widget> children: const [] })
Row 组件只有这一个构造方法,并且也没有什么必传参数,所以说 Row 组件其实是很简单的。
crossAxisAlignment:子组件沿着 Cross 轴(在 Row 中是纵轴)如何摆放,其实就是子组件对齐方式,可选值有:
CrossAxisAlignment.start:子组件在 Row 中顶部对齐。
CrossAxisAlignment.end:子组件在 Row 中底部对齐。
CrossAxisAlignment.center:子组件在 Row 中居中对齐。
CrossAxisAlignment.stretch:拉伸填充满父布局。
CrossAxisAlignment.baseline:在 Row 组件中会报错。
mainAxisAlignment:子组件沿着 Main 轴(在 Row 中是横轴)如何摆放,其实就是子组件排列方式,可选值有:
MainAxisAlignment.start:靠左排列。
MainAxisAlignment.end:靠右排列。
MainAxisAlignment.center:居中排列。
MainAxisAlignment.spaceAround:每个子组件左右间隔相等,也就是 margin 相等。
MainAxisAlignment.spaceBetween:两端对齐,也就是第一个子组件靠左,最后一个子组件靠右,剩余组件在中间平均分散排列。
MainAxisAlignment.spaceEvenly:每个子组件平均分散排列,也就是宽度相等。
mainAxisSize:Main 轴大小,可选值有:
MainAxisSize.max:相当于 Android 的 match_parent。
MainAxisSize.min:相当于 Android 的 wrap_content。
textBaseline:不太理解。
textDirection:子组件排列顺序,可选值有:
TextDirection.ltr:从左往右开始排列。
TextDirection.rtl:从右往左开始排列。
verticalDirection:确定如何在垂直方向摆放子组件,以及如何解释 start 和 end,指定 height 可以看到效果,可选值有:
VerticalDirection.up:Row 从下至上开始摆放子组件,此时我们看到的底部其实是顶部。
VerticalDirection.down:Row 从上至下开始摆放子组件,此时我们看到的顶部就是顶部。
children:子组件,值是一个 Widget 数组。
下面是一个设置了上述属性的 Demo:
- import 'package:flutter/material.dart';
-
- void main() => runApp(MyApp());
-
- class MyApp extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- // TODO: implement build
- return MaterialApp(
- title: "Row",
- debugShowCheckedModeBanner: false,
- home: Scaffold(
- appBar: AppBar(
- title: Text("Row"),
- ),
- body: Container(
- height: 300,
- child: Row(
- //子组件沿着 Cross 轴(在 Row 中是纵轴)如何摆放,其实就是子组件对齐方式,可选值有:
- //CrossAxisAlignment.start:子组件在 Row 中顶部对齐
- //CrossAxisAlignment.end:子组件在 Row 中底部对齐
- //CrossAxisAlignment.center:子组件在 Row 中居中对齐
- //CrossAxisAlignment.stretch:拉伸填充满父布局
- //CrossAxisAlignment.baseline:在 Row 组件中会报错
- crossAxisAlignment: CrossAxisAlignment.start,
- //子组件沿着 Main 轴(在 Row 中是横轴)如何摆放,其实就是子组件排列方式,可选值有:
- //MainAxisAlignment.start:靠左排列
- //MainAxisAlignment.end:靠右排列
- //MainAxisAlignment.center:居中排列
- //MainAxisAlignment.spaceAround:每个子组件左右间隔相等,也就是 margin 相等
- //MainAxisAlignment.spaceBetween:两端对齐,也就是第一个子组件靠左,最后一个子组件靠右,剩余组件在中间平均分散排列
- //MainAxisAlignment.spaceEvenly:每个子组件平均分散排列,也就是宽度相等
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- //Main 轴大小,可选值有:
- //MainAxisSize.max:相当于 Android 的 match_parent
- //MainAxisSize.min:相当于 Android 的 wrap_content
- mainAxisSize: MainAxisSize.max,
- //不太理解
- // textBaseline: TextBaseline.alphabetic,
- //子组件排列顺序,可选值有:
- //TextDirection.ltr:从左往右开始排列
- //TextDirection.rtl:从右往左开始排列
- textDirection: TextDirection.ltr,
- //确定如何在垂直方向摆放子组件,以及如何解释 start 和 end,指定 height 可以看到效果,可选值有:
- //VerticalDirection.up:Row 从下至上开始摆放子组件,此时我们看到的底部其实是顶部
- //VerticalDirection.down:Row 从上至下开始摆放子组件,此时我们看到的顶部就是顶部
- verticalDirection: VerticalDirection.down,
- children: <Widget>[
- Container(
- color: Color(0xFFFF0000),
- child: Text(
- "Text1",
- style: TextStyle(fontSize: 30.0),
- ),
- ),
- Container(
- color: Color(0xFFFFFF00),
- child: Text(
- "Text2",
- style: TextStyle(fontSize: 30.0),
- ),
- ),
- Container(
- color: Color(0xFF00FF00),
- child: Text(
- "Text3",
- style: TextStyle(fontSize: 30.0),
- ),
- ),
- Container(
- color: Color(0xFF0000FF),
- child: Text(
- "Text4",
- style: TextStyle(fontSize: 30.0),
- ),
- ),
- ],
- ),
- ),
- ),
- );
- }
- }
运行效果如下:
可以看到的是 4 个子组件的宽度是包裹了文字,有时候我们希望它们能够平分 Row 的宽度,这时候只需要用 Expanded 组件包裹一下子组件就行了:
- children: <Widget>[
- Expanded(
- child: Container(
- color: Color(0xFFFF0000),
- child: Text(
- "Text1",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- child: Container(
- color: Color(0xFFFFFF00),
- child: Text(
- "Text2",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- child: Container(
- color: Color(0xFF00FF00),
- child: Text(
- "Text3",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- child: Container(
- color: Color(0xFF0000FF),
- child: Text(
- "Text4",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
运行效果如下:
Expanded 组件的使用很简单,除了一个必传的参数 child 以为,还有一个 flex 属性,它就相当于 LinearLayout 中的 weight,默认是 1,如果指定为 2 就表示它包裹的子组件占据的空间为总数的两份,如:
- children: <Widget>[
- Expanded(
- child: Container(
- color: Color(0xFFFF0000),
- child: Text(
- "Text1",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- child: Container(
- color: Color(0xFFFFFF00),
- child: Text(
- "Text2",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- child: Container(
- color: Color(0xFF00FF00),
- child: Text(
- "Text3",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- flex: 2,
- child: Container(
- color: Color(0xFF0000FF),
- child: Text(
- "Text4",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- ],
一共是 4 个子组件,最后一个子组件指定了 flex 为 2,其他没有指定 flex 属性的子组件默认 flex 为 1,1+1+1+2 = 5,总共把 Row 组件的宽度分为 5 份,最后一个子组件的宽度占 5 份中的 2 份,其余子组件各占 5 份中的 1 份:
Column 就相当于一个 orientation 为 vertical 的 LinearLayout。它的用法完全与 Row 一样,可以说会了 Row 组件就会了 Column 组件,所以不详细介绍,将上面 Demo 中的 Row 改为 Column 看看效果:
- import 'package:flutter/material.dart';
-
- void main() => runApp(MyApp());
-
- class MyApp extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- // TODO: implement build
- return MaterialApp(
- title: "Row",
- debugShowCheckedModeBanner: false,
- home: Scaffold(
- appBar: AppBar(
- title: Text("Row"),
- ),
- body: Container(
- child: Column(
- //子组件沿着 Cross 轴(在 Row 中是纵轴)如何摆放,其实就是子组件对齐方式,可选值有:
- //CrossAxisAlignment.start:子组件在 Row 中顶部对齐
- //CrossAxisAlignment.end:子组件在 Row 中底部对齐
- //CrossAxisAlignment.center:子组件在 Row 中居中对齐
- //CrossAxisAlignment.stretch:拉伸填充满父布局
- //CrossAxisAlignment.baseline:在 Row 组件中会报错
- crossAxisAlignment: CrossAxisAlignment.start,
- //子组件沿着 Main 轴(在 Row 中是横轴)如何摆放,其实就是子组件排列方式,可选值有:
- //MainAxisAlignment.start:靠左排列
- //MainAxisAlignment.end:靠右排列
- //MainAxisAlignment.center:居中排列
- //MainAxisAlignment.spaceAround:每个子组件左右间隔相等,也就是 margin 相等
- //MainAxisAlignment.spaceBetween:两端对齐,也就是第一个子组件靠左,最后一个子组件靠右,剩余组件在中间平均分散排列
- //MainAxisAlignment.spaceEvenly:每个子组件平均分散排列,也就是宽度相等
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- //Main 轴大小,可选值有:
- //MainAxisSize.max:相当于 Android 的 match_parent
- //MainAxisSize.min:相当于 Android 的 wrap_content
- mainAxisSize: MainAxisSize.max,
- //不太理解
- // textBaseline: TextBaseline.alphabetic,
- //子组件排列顺序,可选值有:
- //TextDirection.ltr:从左往右开始排列
- //TextDirection.rtl:从右往左开始排列
- textDirection: TextDirection.ltr,
- //确定如何在垂直方向摆放子组件,以及如何解释 start 和 end,指定 height 可以看到效果,可选值有:
- //VerticalDirection.up:Row 从下至上开始摆放子组件,此时我们看到的底部其实是顶部
- //VerticalDirection.down:Row 从上至下开始摆放子组件,此时我们看到的顶部就是顶部
- verticalDirection: VerticalDirection.down,
- children: <Widget>[
- Expanded(
- child: Container(
- width: double.infinity,
- color: Color(0xFFFF0000),
- child: Text(
- "Text1",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- child: Container(
- width: double.infinity,
- color: Color(0xFFFFFF00),
- child: Text(
- "Text2",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- child: Container(
- width: double.infinity,
- color: Color(0xFF00FF00),
- child: Text(
- "Text3",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- Expanded(
- flex: 2,
- child: Container(
- width: double.infinity,
- color: Color(0xFF0000FF),
- child: Text(
- "Text4",
- style: TextStyle(fontSize: 30.0),
- ),
- )),
- ],
- ),
- ),
- ),
- );
- }
- }
运行效果如下:
Flutter 将 Android 中一个 LinearLayout 横纵向拆成了两个组件,还是觉得怪麻烦的,还好两个组件的属性没有上面区别,我忍了。Row 和 Column 是最基本的布局组件,算是基础中的基础呀。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。