Column 垂直布局
Column({
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 <Widget>[],
}) : super(
children: children,
key: key,
direction: Axis.vertical,
mainAxisAlignment: mainAxisAlignment,
mainAxisSize: mainAxisSize,
crossAxisAlignment: crossAxisAlignment,
textDirection: textDirection,
verticalDirection: verticalDirection,
textBaseline: textBaseline,
);
children:子控件集合
mainAxisAlignment:主轴方向的排布方式,由于是竖向布局,其主轴是竖向的垂直线
1、center:主轴中心
2、start:主轴起点
3、end:主轴末尾
4、spaceAround:主轴中间空白区域均分,首尾空白区域为1/2
5、spaceBetween:主轴中间空白区域均分,首尾没有空白区域
6、spaceEvenly:主轴中间空白区域均分,首尾平分空白区域
mainAxisSize:主轴方向占有空间的值
1、max:占用最大空间
2、min:占用最小空间
crossAxisAlignment:侧轴方向的排布方式,由于是竖向布局,其侧轴是横向的水平线
1、baseline:侧轴与baseline对齐
2、center:侧轴居中显示
3、end:侧轴末尾显示
4、start:侧轴起点显示
5、stretch:侧轴填满显示
textDirection:文字的排布方式
1、TextDirection.ltr:从左到右
2、TextDirection.rtl:从右到左
verticalDirection:子控件的排布方式
1、down:从左上角到右下角进行布局
2、up:从右下角到左上角进行布局
textBaseline:文字的基准线
详情可参考:Flutter: 图解 Row 与 Column
Padding
const Padding({
Key key,
@required this.padding,
Widget child,
}) : assert(padding != null),
super(key: key, child: child);
child:子控件
当child为空的时候,会产生一个宽为left+right,高为top+bottom的区域;
当child不为空的时候,Padding会将布局约束传递给child,根据设置的padding属性,缩小child的布局尺寸。然 Padding将自己调整到child设置了padding属性的尺寸,在child周围创建空白区域。
padding:EdgeInsets 设置填充的值
Stack
Stack({
Key key,
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
this.clipBehavior = Clip.hardEdge,
List<Widget> children = const <Widget>[],
}) : assert(clipBehavior != null),
super(key: key, children: children);
alignment
此参数决定如何去对齐没有定位(没有使用Positioned)或部分定位的子组件。所谓部分定位,
在这里特指只在某一个轴上定位:left、right为横轴,top、bottom为纵轴,只要包含某个轴上
的一个定位属性就算在该轴上有定位。
textDirection
和Row、Wrap的textDirection功能一样,都用于确定alignment对齐的参考系,即:textDirection的
值为TextDirection.ltr,那么alignment的start则代表左,end就是代表右,即从左往右的顺序;如果
textDirection的值为TextDirection.rtl,那么alignment的start则代表右,end就是代表左,即从
右往左的顺序。
fit
此参数用于确定没有定位的子组件如何去适应Stack的大小。StackFit.loose代表使用子组件的大小,
StackFit.expand表示扩伸到Stack大小。
overflow
此属性决定如何显示超出Stack显示空间的子组件;overflow的值为Overflow.clip时,超出部分会被
裁剪,overflow的值为Overflow.visible时则不会。
代码
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 100, 0, 0),
child: Container(
color: Colors.blue,
width: MediaQuery.of(context).size.width,
height: 100,
child: Stack(
children: <Widget>[
Positioned(
child: ClipPath(
clipper:StartTimeClipper() ,
child: Container(
color: Colors.red,
child: GestureDetector(
onTap: (){
print("点击红色");
},
),
),
)
),
Positioned(
child: ClipPath(
clipper: EndTimeClipper(),
child: Container(
color: Colors.yellow,
child: GestureDetector(
onTap:() {
print("点击黄色");
},
),
),
),
),
],
),
),
),
],
);
}
}
class StartTimeClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final path = Path();
path.lineTo(size.width * 1/2 , 0.0);
path.lineTo(size.width * 1/4, size.height);
path.lineTo(0.0, size.height);
path.close();
return path;
}
@override
bool shouldReclip(StartTimeClipper oldClipper) => false;
}
class EndTimeClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final path = Path();
path.moveTo(size.width * 1/2 , 0.0);
path.lineTo(size.width , 0.0);
path.lineTo(size.width, size.height);
path.lineTo(size.width * 1/4, size.height);
path.close();
return path;
}
@override
bool shouldReclip(EndTimeClipper oldClipper) => false;
}