Column组件即垂直布局控件,能够将子组件垂直排列。其实你学会了Row组件就基本掌握了Column组件,你可打开Row()组件的构造函数对比一下,它们的参数完全是一模一样的,只是排列方向不同,下面一起探究Column布局吧。
来看一下Column()组件的源码定义:
/// ## Layout algorithm
///
/// _This section describes how a [Column] is rendered by the framework._
/// _See [BoxConstraints] for an introduction to box layout models._
///
/// Layout for a [Column] proceeds in six steps:
///
/// 1. Layout each child a null or zero flex factor (e.g., those that are not
/// [Expanded]) with unbounded vertical constraints and the incoming
/// horizontal constraints. If the [crossAxisAlignment] is
/// [CrossAxisAlignment.stretch], instead use tight horizontal constraints
/// that match the incoming max width.
/// 2. Divide the remaining vertical space among the children with non-zero
/// flex factors (e.g., those that are [Expanded]) according to their flex
/// factor. For example, a child with a flex factor of 2.0 will receive twice
/// the amount of vertical space as a child with a flex factor of 1.0.
/// 3. Layout each of the remaining children with the same horizontal
/// constraints as in step 1, but instead of using unbounded vertical
/// constraints, use vertical constraints based on the amount of space
/// allocated in step 2. Children with [Flexible.fit] properties that are
/// [FlexFit.tight] are given tight constraints (i.e., forced to fill the
/// allocated space), and children with [Flexible.fit] properties that are
/// [FlexFit.loose] are given loose constraints (i.e., not forced to fill the
/// allocated space).
/// 4. The width of the [Column] is the maximum width of the children (which
/// will always satisfy the incoming horizontal constraints).
/// 5. The height of the [Column] is determined by the [mainAxisSize] property.
/// If the [mainAxisSize] property is [MainAxisSize.max], then the height of
/// the [Column] is the max height of the incoming constraints. If the
/// [mainAxisSize] property is [MainAxisSize.min], then the height of the
/// [Column] is the sum of heights of the children (subject to the incoming
/// constraints).
/// 6. Determine the position for each child according to the
/// [mainAxisAlignment] and the [crossAxisAlignment]. For example, if the
/// [mainAxisAlignment] is [MainAxisAlignment.spaceBetween], any vertical
/// space that has not been allocated to children is divided evenly and
/// placed between the children.
///
/// See also:
///
/// * [Row], for a horizontal equivalent.
/// * [Flex], if you don't know in advance if you want a horizontal or vertical
/// arrangement.
/// * [Expanded], to indicate children that should take all the remaining room.
/// * [Flexible], to indicate children that should share the remaining room but
/// that may size smaller (leaving some remaining room unused).
/// * [SingleChildScrollView], whose documentation discusses some ways to
/// use a [Column] inside a scrolling container.
/// * [Spacer], a widget that takes up space proportional to its flex value.
/// * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
class Column extends Flex {
/// Creates a vertical array of children.
///
/// The [direction], [mainAxisAlignment], [mainAxisSize],
/// [crossAxisAlignment], and [verticalDirection] arguments must not be null.
/// If [crossAxisAlignment] is [CrossAxisAlignment.baseline], then
/// [textBaseline] must not be null.
///
/// The [textDirection] argument defaults to the ambient [Directionality], if
/// any. If there is no ambient directionality, and a text direction is going
/// to be necessary to disambiguate `start` or `end` values for the
/// [crossAxisAlignment], the [textDirection] must not be null.
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, //Clomun组件的主轴默认对齐布局方式
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,//Clomun组件的交叉轴默认对齐布局方式
TextDirection textDirection,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline textBaseline,
List<Widget> children = const <Widget>[],
}) : super(
children: children,
key: key,
direction: Axis.vertical,
mainAxisAlignment: mainAxisAlignment,
mainAxisSize: mainAxisSize,
crossAxisAlignment: crossAxisAlignment,
textDirection: textDirection,
verticalDirection: verticalDirection,
textBaseline: textBaseline,
);
}
属性名即作用:
mainAxisAlignment: 主轴的排列方式,也是Column()组件布局的主轴布局方式
mainAxisSize: 主轴应该占据多少空间,取值max为最大值,取值min为最小值。
crossAxisAlignment: 次轴的排列方式,也是Column()组件布局的次轴布局方式
上面的官方英文介绍和Row()组件很像,这里就不再翻译。可以看出Column()组件也有主轴和交叉轴(副轴、次轴都是指的交叉轴),只不过Column()组件的主轴方向是竖直方向了,如图:
这时在回过头看Row()组件的主轴、交叉轴方向是什么样的,可以对比下。
网上很多的总结:
Row()组件的主轴:孩子组件排列的方向是水平方向,所以主轴是水平方向,交叉轴与主轴垂直。
Column()组件的主轴:孩子组件排列的方向是竖直方向,所以主轴是竖直方向,交叉轴与主轴垂直。
布局的对齐方式
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center
对齐方式的枚举类:
enum MainAxisAlignment {
/// Place the children as close to the start of the main axis as possible.
///
/// If this value is used in a horizontal direction, a [TextDirection] must be
/// available to determine if the start is the left or the right.
///
/// If this value is used in a vertical direction, a [VerticalDirection] must be
/// available to determine if the start is the top or the bottom.
start,
/// Place the children as close to the end of the main axis as possible.
///
/// If this value is used in a horizontal direction, a [TextDirection] must be
/// available to determine if the end is the left or the right.
///
/// If this value is used in a vertical direction, a [VerticalDirection] must be
/// available to determine if the end is the top or the bottom.
end,
/// Place the children as close to the middle of the main axis as possible.
center,
/// Place the free space evenly between the children.
spaceBetween,
/// Place the free space evenly between the children as well as half of that
/// space before and after the first and last child.
spaceAround,
/// Place the free space evenly between the children as well as before and
/// after the first and last child.
spaceEvenly,
}
/// How the children should be placed along the cross axis in a flex layout.
///
/// See also:
///
/// * [Column], [Row], and [Flex], the flex widgets.
/// * [RenderFlex], the flex render object.
enum CrossAxisAlignment {
/// Place the children with their start edge aligned with the start side of
/// the cross axis.
///
/// For example, in a column (a flex with a vertical axis) whose
/// [TextDirection] is [TextDirection.ltr], this aligns the left edge of the
/// children along the left edge of the column.
///
/// If this value is used in a horizontal direction, a [TextDirection] must be
/// available to determine if the start is the left or the right.
///
/// If this value is used in a vertical direction, a [VerticalDirection] must be
/// available to determine if the start is the top or the bottom.
start,
/// Place the children as close to the end of the cross axis as possible.
///
/// For example, in a column (a flex with a vertical axis) whose
/// [TextDirection] is [TextDirection.ltr], this aligns the right edge of the
/// children along the right edge of the column.
///
/// If this value is used in a horizontal direction, a [TextDirection] must be
/// available to determine if the end is the left or the right.
///
/// If this value is used in a vertical direction, a [VerticalDirection] must be
/// available to determine if the end is the top or the bottom.
end,
/// Place the children so that their centers align with the middle of the
/// cross axis.
///
/// This is the default cross-axis alignment.
center,
/// Require the children to fill the cross axis.
///
/// This causes the constraints passed to the children to be tight in the
/// cross axis.
stretch,
/// Place the children along the cross axis such that their baselines match.
///
/// If the main axis is vertical, then this value is treated like [start]
/// (since baselines are always horizontal).
baseline,
}
对齐方式和Row()组件的枚举类一样,不再累述!
灵活与非灵活布局
同样Column()组件的布局方式,其孩子组件也是分灵活布局和非灵活布局,即是否使用Expanded()组件包裹。同样也有 "flex factor" [伸缩因子] 的属性设置。
下面直接给出几个使用示例:
非灵活Column()布局:
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title:Text('优品酒家')),
body:Container(
child: Column(
children:[
Container(
child:new RaisedButton(
onPressed: (){
},
color:Colors.redAccent,
child:new Text('红色按钮')
),
width: 100.0,
height: 150.0,
),
Container(
child:new RaisedButton(
onPressed: (){
},
color:Colors.orangeAccent,
child: new Text('黄色按钮'),
),
width: 100.0,
height: 150.0,
),
Container(
child: new RaisedButton(
onPressed: (){
},
color:Colors.pinkAccent,
child:new Text('粉色按钮')
),
width: 100.0,
height: 150.0,
)
]
),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
)
);
}
}
代码运行效果图,可以看出Column()组件主轴默认的对齐方式是start,而交叉轴默认的排列方式是center,在上面的构造方法中也能体现:
设置灵活的Column()组件布局,并且主轴的排列方式为center,交叉轴的排列方式为start,代码如下:
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title:Text('优品酒家')),
body:Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,//灵活布局主轴方向上看不出来了
crossAxisAlignment: CrossAxisAlignment.start,
children:[
Expanded(
child: Container(
child:new RaisedButton(
onPressed: (){
},
color:Colors.redAccent,
child:new Text('红色按钮')
),
width: 100.0,
height: 150.0,
)
),
Expanded(
child: Container(
child:new RaisedButton(
onPressed: (){
},
color:Colors.orangeAccent,
child: new Text('黄色按钮'),
),
width: 100.0,
height: 150.0,
)
),
Expanded(
child: Container(
child: new RaisedButton(
onPressed: (){
},
color:Colors.pinkAccent,
child:new Text('粉色按钮')
),
width: 100.0,
height: 150.0,
)
)
]
),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
)
);
}
}
代码运行的效果图如下:
对于伸缩因子flex属性示例如下:
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title:Text('优品酒家')),
body:Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children:[
Expanded(
flex: 2,
child: Container(
child:new RaisedButton(
onPressed: (){
},
color:Colors.redAccent,
child:new Text('红色按钮 flex: 2')
),
width: 100.0,
)
),
Expanded(
flex: 1,
child: Container(
child:new RaisedButton(
onPressed: (){
},
color:Colors.orangeAccent,
child: new Text('黄色按钮 flex: 1'),
),
width: 100.0,
)
),
Container(
child: new RaisedButton(
onPressed: (){
},
color:Colors.pinkAccent,
child:new Text('粉色按钮')
),
width: 100.0,
height: 150.0,
)
]
),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
)
);
}
}
代码运行效果如下:
好了,Column()组件布局总结就到这里!
遇见即使缘分,感谢每一位爱进步的小伙伴的不吝时间阅读。岁月如潺潺泉水般流淌,唯有学习与强大自我,才不负韶华!
下一篇总结:Flutter常用组件系列总结- Stack()组件层叠布局(六) https://mp.csdn.net/editor/html/110289561
原文地址:https://blog.csdn.net/luqingshuai_eloong/article/details/110284737
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。