Flutter中的Stack,相当于Android里的FrameLayout和RelativeLayout。
层叠布局和Web中的绝对定位、Android中的Frame布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。绝对定位允许子组件堆叠起来(按照代码中声明的顺序)。
Flutter中使用Stack
和Positioned
这两个组件来配合实现绝对定位。Stack
允许子组件堆叠,而Positioned
用于根据Stack
的四个角来确定子组件的位置。
Stack常用属性值 | 含义 |
---|---|
alignment | 指定未定位或部分定位widget的对齐方式 |
textDirection | 用于确定alignment对齐的参考系 |
fit | 此参数用于确定没有定位的子组件如何去适应Stack的大小 |
overflow | 此属性决定如何显示超出Stack显示空间的子组件 |
Stack({
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
})
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.clip
时,超出部分会被剪裁(隐藏),值为Overflow.visible
时则不会。
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
left
、top
、right
、 bottom
分别代表离Stack
左、上、右、底四边的距离。
width
和height
用于指定需要定位元素的宽度和高度。
注意,Positioned
的width
、height
和其它地方的意义稍微有点区别,此处用于配合left
、top
、right
、 bottom
来定位组件。
举个例子,在水平方向时,你只能指定left
、right
、width
三个属性中的两个,如指定left
和width
后,right
会自动算出(left
+width
),如果同时指定三个属性则会报错,垂直方向同理。
在下面的例子中,我们通过对几个Text
组件的定位来演示Stack
和Positioned
的特性:
import 'package:flutter/material.dart';
class StackDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text("层叠布局"),
),
//通过ConstrainedBox来确保Stack占满屏幕
body: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: Stack(
alignment: Alignment.center,
//指定未定位或部分定位widget的对齐方式
textDirection: TextDirection.rtl,
fit: StackFit.loose,
overflow: Overflow.clip,
children: <Widget>[
Container(
child:
Text("Hello world", style: TextStyle(color: Colors.white)),
color: Colors.red,
),
Positioned(
left: 18.0,
child: Text("left"),
),
Positioned(
top: 18.0,
child: Text("top"),
),
Positioned(
right: 18.0,
child: Text("right"),
),
Positioned(
bottom: 18.0,
child: Text("bottom"),
)
],
),
));
}
}
void main() {
runApp(new MaterialApp(
title: "层叠布局案例",
theme: new ThemeData(primaryColor: Colors.deepOrangeAccent),
home: new StackDemo(),
));
}
效果图:
由于第一个子文本组件Text("Hello world")
没有指定定位,并且alignment
值为Alignment.center
,所以它会居中显示。第二个子文本组件Text("left")
只指定了水平方向的定位(left
),所以属于部分定位,即垂直方向上没有定位,那么它在垂直方向的对齐方式则会按照alignment
指定的对齐方式对齐,即垂直方向居中。
同理,其他Text与第二个Text原理一样。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有