如果说 Row 和 Column 相当于 Android 的 LinearLayout 的话,那么 Stack 就有点像 Android 中 FrameLayout,它可以使子组件堆叠起来,但是它比 FrameLayout 要强大,它可以控制子组件的位置,使用起来也是很简单的。
Stack({Key key, AlignmentGeometry alignment: AlignmentDirectional.topStart, TextDirection textDirection, StackFit fit: StackFit.loose, Overflow overflow: Overflow.clip, List
Stack 只有这一个构造方法,而且也没有必须指定的属性,但是一般都会设置 children 属性,不然也没有什么意义。
alignment:子组件对齐方式,同 Container 的 alignment 属性一样的,它指定的是所有子组件的对齐方式,所以建议在只有两个子组件的时候使用,如果有三个及以上的子组件时,建议使用 Positioned 包裹子组件来决定子组件的位置,具体参考 2.1 Positioned,alignment 的可选值有:
AlignmentDirectional.topCenter:子组件垂直靠顶部水平居中对齐。
AlignmentDirectional.topRight:子组件垂直靠顶部水平靠右对齐。
AlignmentDirectional.centerLeft:子组件垂直居中水平靠左对齐。
AlignmentDirectional.center:子组件垂直和水平居中都对齐。
AlignmentDirectional.centerRight:子组件垂直居中水平靠右对齐。
AlignmentDirectional.bottomLeft:子组件垂直靠底部水平靠左对齐。
AlignmentDirectional.bottomCenter:子组件垂直靠底部水平居中对齐。
AlignmentDirectional.bottomRight:子组件垂直靠底部水平靠右对齐。
也可以使用 alignmentDirectional(start,y) 指定具体的偏移量,start 就相当于 x,它是以整个组件的中心为坐标原点,x、y 偏移量取值范围为 [-1,1],如果 x 的偏移量大于 0,则表示向右偏移,小于 0 则向左偏移;如果 y 轴的偏移量大于 0 则向下偏移,小于 0 则向上偏移。
textDirection:子组件排列方向,可选值有:
TextDirection.ltr:从左往右排列。
TextDirection.rtl:从右往左排列。
fit:如何确定没有使用 Position 包裹的子组件的大小,可选值有:
StackFit.loose:子组件宽松取值,可以从 min 到 max。
StackFit.expand:子组件取最大值。
StackFit.passthrough:不改变子组件约束条件。
overflow:超出部分的处理方式,可选值有 Overflow.clip 和 Overflow.visible,不过我没有看到该属性的效果。
下面是一个设置了上述属性的 Demo:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
//是否显示 debug 标签
debugShowCheckedModeBanner: false,
title: "Stack",
home: Scaffold(
appBar: AppBar(
title: Text("Stack"),
),
body: Container(
child: Stack(
//子组件对齐方式,同 Container 的 alignment 属性一样的,它指定的是所有子组件的对齐方式,所以建议在只有两个子组件的时候
//使用,如果有三个及以上的子组件时,建议使用 Positioned 包裹子组件来决定子组件的位置,alignment 的可选值有:
//AlignmentDirectional.topCenter:垂直靠顶部水平居中对齐
//AlignmentDirectional.topRight:垂直靠顶部水平靠右对齐
//AlignmentDirectional.centerLeft:垂直居中水平靠左对齐
//AlignmentDirectional.center:垂直和水平居中都对齐
//AlignmentDirectional.centerRight:垂直居中水平靠右对齐
//AlignmentDirectional.bottomLeft:垂直靠底部水平靠左对齐
//AlignmentDirectional.bottomCenter:垂直靠底部水平居中对齐
//AlignmentDirectional.bottomRight:垂直靠底部水平靠右对齐
//也可以像我一样指定具体的偏移量,它是以整个组件的中心为坐标原点,x、y 偏移量取值范围为 [-1,1],如果 x 的偏移量大于 0
//则表示向右偏移,小于 0 则向左偏移;如果 y 轴的偏移量大于 0 则向下偏移,小于 0 则向上偏移。
alignment: AlignmentDirectional(0.8, -0.8),
//子组件排列方向,可选值有:
//TextDirection.ltr:从左往右排列
//TextDirection.rtl:从右往左排列
textDirection: TextDirection.ltr,
//如何确定没有使用 Position 包裹的子组件的大小,可选值有:
//StackFit.loose:子组件宽松取值,可以从 min 到 max
//StackFit.expand:子组件取最大值
//StackFit.passthrough:不改变子组件约束条件
fit: StackFit.loose,
//超出部分的处理方式,可选值有 Overflow.clip 和 Overflow.visible,不过我没有看到该属性的效果
// overflow: Overflow.clip,
children: [
CircleAvatar(
backgroundImage: AssetImage("assets/images/a.jpg"),
radius: 100,
),
Text(
"Itachi",
style: TextStyle(fontSize: 30, color: Color(0xFF000000)),
),
Positioned(
//距离左边的距离
left: 10,
//距离顶部的距离
// top: 10,
//距离右边的距离,设置 left 后该距离失效
// right: 10,
//距离底部的距离,设置 top 后该距离失效
bottom: 10,
// //子组件的宽、高,注意,宽高与 top、left、bottom、right
// width: 100,
// height: 100,
child: Text(
"鼬",
style: TextStyle(fontSize: 40, color: Color(0xFF000000)),
),
),
],
),
),
),
);
}
}
运行效果如下:
用来在 Stack 组件中辅助子组件定位的组件,建议在有三个及以上子组件的复杂布局时使用,它的常用属性有如下 6 个:
left:距离左边的距离。
top:距离顶部的距离。
right:距离右边的距离,设置 left 后该距离失效。
bottom:距离底部的距离,设置 top 后该距离失效。
width 和 height:子组件的宽。
height:子组件的高。
注意,width、left、right 不能同时设置,height、top、bottom 也不能同时设置。
stack 可以应对需要子组件堆叠的场景,而且使用 Positioned 辅助后定位子组件可以是相当灵活。