Column —— 行布局
一、使用方法
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,//设置主轴方向上的对齐方式
MainAxisSize mainAxisSize = MainAxisSize.max,//设置主轴方向占有空间的值,默认是max (MainAxisSize的取值有两种:max:根据传入的布局约束条件,最大化主轴方向的可用空间;min:与max相反,是最小化主轴方向的可用空间;)
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,//设置交叉轴方向上的对齐方式
TextDirection textDirection,//设置文字的排列方向,可以通过在设置Row主轴的基础上设置 改变主轴的方向
VerticalDirection verticalDirection = VerticalDirection.down,//设置主轴的基础上,可以通过设置verticalDirection改变主轴的方向
TextBaseline textBaseline,//设置
List<Widget> children = const <Widget>[],//子控件列表
})
复制代码
1. 用于在垂直方向中显示其子项,另通过
//todo 例子1. Column,用于在垂直方向中显示其子项。
Column(
children: <Widget>[
//Expanded 用于展开Row,Column或Flex的子项的窗口小部件。
//使用“ Expanded”小部件可以扩展行,列或Flex的子项 以填充主轴中的可用空间(例如,水平为行或垂直为列)。如果扩展了多个子节点,则根据弹性因子将可用空间划分为多个子节点。
Expanded(
//构造函数 扩展({ Key key, int flex:1, @required Widget child })
//@required child 为必填参数,指要填充的子控件
child: Text('Deliver features faster', textAlign: TextAlign.center),
// child: Text('Deliver ', textAlign: TextAlign.center),
//孩子最多可以与可用空间一样大(但允许更小)
flex: 1,
//键
key: ValueKey("1"),
),
Expanded(
child: Text('Craft beautiful', textAlign: TextAlign.center),
//通过还在控件去强制填充可以用空间,会向两边挤压,以适应这个子控件
flex: 1,
),
Expanded(
flex: 2,
child: FittedBox(
fit: BoxFit.contain, // otherwise the logo will be tiny
child: const FlutterLogo(),
),
),
],
)
复制代码
2. 为什么我的列有黄色和黑色警告条纹?
如果列非灵活内容(那些未包含在 Expanded或Flexible小部件中的内容)在一起比列本身宽,则说该列已溢出。当列溢出时,该列没有任何剩余空间可在其Expanded和Flexible 子级之间共享。该列通过在溢出的边缘上绘制黄色和黑色条纹警告框来报告此情况。如果列外侧有空间,则溢出量以红色字体打印。
//例子2 为什么我的列有黄色和黑色警告条纹
Column(
children: <Widget>[
const FlutterLogo(
size: 200,
),
const Icon(
Icons.account_circle,
size: 300,
color: Colors.blue,
),
const Icon(
Icons.ac_unit,
size: 200,
color: Colors.yellow,
)
],
)
复制代码
3. 通过Expanded 包裹自适应均分分布
可以解决例子2中的问题,将第二个子项包装在Expanded小部件中,该小部件告诉列应该为该子项提供剩余空间:
//例子3 通过Expanded 包裹自适应均分分布
//解决方法 解决方法是将第二个子项包装在Expanded小部件中,该小部件告诉该列应该为该子项提供剩余空间:
Column(
children: <Widget>[
const Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: const FlutterLogo(),
)
),
const Expanded(
flex: 1,
child: Icon(
Icons.account_circle,
size: 300,
color: Colors.blue,
),
),
Expanded(
flex: 1,
child: Icon(
Icons.access_time,
size: 300,
color: Colors.yellow,
),
),
],
)
复制代码
二、常用属性
1. 设置主轴方向上的对齐方式 —— mainAxisAlignment
-
在水平方向控件(Row):
-
MainAxisAlignment是水平的,默认起始位置在左边,排列方向为从左至右,此时可以通过textDirection来改变MainAxisAlignment的起始位置和排列方向
-
在垂直方向的控件中(Column) :
-
MainAxisAlignment是垂直的,默认起始位置在上边,排列方向为从上至下,此时可以通过verticalDirection来改变MainAxisAlignment的起始位置及排列方向
-
MainAxisAlignment 的枚举类型
enum MainAxisAlignment {
//将子控件放在主轴的开始位置
start,
//将子控件放在主轴的结束位置
end,
//将子控件放在主轴的中间位置
center,
//将主轴空白位置进行均分,排列子元素,手尾没有空隙
spaceBetween,
//将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
spaceAround,
//将主轴空白区域均分,使各个子控件间距相等
spaceEvenly,
}
复制代码
- 例子
// 例子5
Column(
mainAxisAlignment: MainAxisAlignment.start,
//todo 在设置Column主轴的基础上,可以通过设置verticalDirection改变主轴的方向,
// verticalDirection的默认值为VerticalDirection.down,也就是从上至下的方向
// verticalDirection的默认值为VerticalDirection.up,也就是从下至上的方向
verticalDirection:VerticalDirection.down,
children: <Widget>[
Box("aaaaaaa"),
Box("bbbbbbb"),
Box("ccccccc")
],
)
复制代码
2. 设置交叉轴方向上的对齐方式 —— crossAxisAlignment
-
在水平方向控件(Row):
-
CrossAxisAlignment是垂直的,默认起始位置在中间,排列方向为从上至下,此时可以通过verticalDirection来改变CrossAxisAlignment的起始位置及排列方向
-
在垂直方向的控件中(Column) :
-
CrossAxisAlignment是水平的,默认起始位置在中间,此时可以通过textDirection来改变CrossAxisAlignment的起始位置
-
枚举类型
enum CrossAxisAlignment {
//将子控件放在交叉轴的起始位置
start,
//将子控件放在交叉轴的结束位置
end,
//将子控件放在交叉轴的中间位置
center,
//使子控件填满交叉轴
stretch,
//将子控件放在交叉轴的上,并且与基线相匹配(不常用)
baseline,
}
复制代码
- 例子
//例子 7 在column的基础上设置交叉轴
Column(
mainAxisAlignment: MainAxisAlignment.start,
//todo 默认为start 将子控件放在交叉轴的起始位置
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Box("aaaaaaa"),
Box("bbbbbbb"),
Box("ccccccc"),
Expanded(
flex: 2,
child: Text('Column crossAxisAlignment .'),
)
],
)
复制代码
3. 在设置Column主轴的基础上,可以通过设置verticalDirection改变主轴的方向
// verticalDirection的默认值为VerticalDirection.down,也就是从上至下的方向
// verticalDirection的默认值为VerticalDirection.up,也就是从下至上的方向
复制代码
// 例子5
Column(
mainAxisAlignment: MainAxisAlignment.start,
//todo 在设置Column主轴的基础上,可以通过设置verticalDirection改变主轴的方向,
// verticalDirection的默认值为VerticalDirection.down,也就是从上至下的方向
// verticalDirection的默认值为VerticalDirection.up,也就是从下至上的方向
verticalDirection:VerticalDirection.down,
children: <Widget>[
Box("aaaaaaa"),
Box("bbbbbbb"),
Box("ccccccc")
],
)
复制代码
三、一个完整的例子
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ColumnPageDemo(title: 'FlexPageDemo'),
);
}
}
class ColumnPageDemo extends StatefulWidget {
ColumnPageDemo({Key key, this.title}) : super(key: key);
final String title;
@override
_ColumnPageDemoState createState() => _ColumnPageDemoState();
}
class _ColumnPageDemoState extends State<ColumnPageDemo> {
void _incrementCounter() {
setState(() {
});
}
//描述此窗口小部件表示的用户界面部分
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
//todo 这里有个要注意的点就是如果父控件没有设置大小,container默认是用子控件的大小去填充父控件的大小
height:MediaQuery.of(context).size.height, //获取屏幕的高度
width: MediaQuery.of(context).size.width,//获取屏幕的宽度,
child:
//todo 例子1. Column,用于在垂直方向中显示其子项。
// Column(
// children: <Widget>[
// //Expanded 用于展开Row,Column或Flex的子项的窗口小部件。
// //使用“ Expanded”小部件可以扩展列,列或Flex的子项 以填充主轴中的可用空间(例如,水平为列或垂直为列)。如果扩展了多个子节点,则根据弹性因子将可用空间划分为多个子节点。
// Expanded(
// //构造函数 扩展({ Key key, int flex:1, @required Widget child })
// //@required child 为必填参数,指要填充的子控件
// child: Text('Deliver features faster', textAlign: TextAlign.center),
child: Text('Deliver ', textAlign: TextAlign.center),
// //孩子最多可以与可用空间一样大(但允许更小)
// flex: 1,
// //键
// key: ValueKey("1"),
// ),
// Expanded(
// child: Text('Craft beautiful', textAlign: TextAlign.center),
// //通过还在控件去强制填充可以用空间,会向两边挤压,以适应这个子控件
// flex: 1,
// ),
// Expanded(
// flex: 2,
// child: FittedBox(
// fit: BoxFit.contain, // otherwise the logo will be tiny
// child: const FlutterLogo(),
// ),
// ),
// ],
// )
//todo 例子2 为什么我的列有黄色和黑色警告条纹?
//如果列非灵活内容(那些未包含在 Expanded或Flexible小部件中的内容)在一起比列本身宽,则说该列已溢出。当列溢出时,该列没有任何剩余空间可在其Expanded和Flexible 子级之间共享。该列通过在溢出的边缘上绘制黄色和黑色条纹警告框来报告此情况。如果列外侧有空间,则溢出量以红色字体打印。
// Column(
// children: <Widget>[
// const FlutterLogo(
// size: 200,
// ),
// const Icon(
// Icons.account_circle,
// size: 300,
// color: Colors.blue,
// ),
// const Icon(
// Icons.ac_unit,
// size: 200,
// color: Colors.yellow,
// )
// ],
// )
//todo 例子3 通过Expanded 包裹自适应均分分布
//解决方法 解决方法是将第二个子项包装在Expanded小部件中,该小部件告诉该列应该为该子项提供剩余空间:
Column(
children: <Widget>[
const Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: const FlutterLogo(),
)
),
const Expanded(
flex: 1,
child: Icon(
Icons.account_circle,
size: 300,
color: Colors.blue,
),
),
Expanded(
flex: 1,
child: Icon(
Icons.access_time,
size: 300,
color: Colors.yellow,
),
),
],
)
//todo 例子4 MainAxisAlignment和CrossAxisAlignment详解
//MainAxisAlignment(主轴)就是与当前控件方向一致的轴,而CrossAxisAlignment(交叉轴)就是与当前控件方向垂直的轴
//在水平方向控件中,Row
//MainAxisAlignment是水平的,默认起始位置在左边,排列方向为从左至右,此时可以通过textDirection来改变MainAxisAlignment的起始位置和排列方向
//CrossAxisAlignment是垂直的,默认起始位置在中间,排列方向为从上至下,此时可以通过verticalDirection来改变CrossAxisAlignment的起始位置及排列方向
//在垂直方向的控件中,Column
//MainAxisAlignment是垂直的,默认起始位置在上边,排列方向为从上至下,此时可以通过verticalDirection来改变MainAxisAlignment的起始位置及排列方向
//CrossAxisAlignment是水平的,默认起始位置在中间,此时可以通过textDirection来改变CrossAxisAlignment的起始位置
// enum MainAxisAlignment {
//
// //将子控件放在主轴的开始位置
// start,
//
// //将子控件放在主轴的结束位置
// end,
//
// //将子控件放在主轴的中间位置
// center,
//
// //将主轴空白位置进列均分,排列子元素,手尾没有空隙
// spaceBetween,
//
// //将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
// spaceAround,
//
// //将主轴空白区域均分,使各个子控件间距相等
// spaceEvenly,
// }
// 在设置主轴的基础上设置 主轴的方向
// textDirection:TextDirection.rtl:从右到左
// textDirection:TextDirection.ltr:从左到右
// 例子4.1
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// //todo 在设置Row主轴的基础上设置 改变主轴的方向
textDirection:TextDirection.rtl,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc")
// ],
// )
例子4.2
// Column(
// mainAxisAlignment: MainAxisAlignment.start,
// //todo 在设置Column主轴的基础上,可以通过设置verticalDirection改变主轴的方向,
// // verticalDirection的默认值为VerticalDirection.down,也就是从上至下的方向
// // verticalDirection的默认值为VerticalDirection.up,也就是从下至上的方向
// verticalDirection:VerticalDirection.down,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc")
// ]
// )
// 例子5
// Column(
// mainAxisAlignment: MainAxisAlignment.start,
// //todo 在设置Column主轴的基础上,可以通过设置verticalDirection改变主轴的方向,
// // verticalDirection的默认值为VerticalDirection.down,也就是从上至下的方向
// // verticalDirection的默认值为VerticalDirection.up,也就是从下至上的方向
// verticalDirection:VerticalDirection.down,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc")
// ],
//
// )
//todo enum CrossAxisAlignment {
// //将子控件放在交叉轴的起始位置
// start,
//
// //将子控件放在交叉轴的结束位置
// end,
//
// //将子控件放在交叉轴的中间位置
// center,
//
使子控件填满交叉轴
// stretch,
//
将子控件放在交叉轴的上,并且与基线相匹配(不常用)
// baseline,
// }
//例子 6 在row的基础上设置交叉轴
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// //todo 默认为start 将子控件放在交叉轴的起始位置
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc")
// ],
// )
//例子 7 在column的基础上设置交叉轴
// Column(
// mainAxisAlignment: MainAxisAlignment.start,
//todo 默认为start 将子控件放在交叉轴的起始位置
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc"),
// Expanded(
// flex: 2,
// child: Text('Column crossAxisAlignment .'),
// )
// ],
// )
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
/**
* 写一个矩形
*/
class Box extends StatelessWidget{
String mStr="";
Box(@required String str){
this.mStr = str;
}
@override
Widget build(BuildContext context) {
return Container(
width: 80,
height: 80,
alignment: Alignment.center,
color: Colors.teal.shade300,
child: Text(mStr),
foregroundDecoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1,
)
),
);
}
}
复制代码