Flutter中的层叠布局 Stack 与Android的FrameLayout相似。子控件是相对于父布局放置的,运行子控件堆叠起来。
1. Stack构造方法:
Stack({
Key key,
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
}) : super(key: key, children: children);
2. Stack属性:
- alignment:
此参数是子控件的对齐方式,默认是AlignmentDirectional.topLeft (左上)。
- textDirection:
子组件排列方向,可选值有:
TextDirection.ltr:从左往右排列。
TextDirection.rtl:从右往左排列
- fit:
用来决定没有Positioned方式时候子Widget的大小,StackFit.loose 指的是子Widget 多大就多大,
StackFit.expand使子Widget的大小和父组件一样大
- overflow:
此属性决定如何显示超出Stack显示空间的子组件;值为Overflow.clip时,超出部分会被剪裁(隐藏),
值为Overflow.visible 时则不会。
import 'package:flutter/material.dart';
class StackPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stack Page'),
),
body: _stackWidget(),
);
}
Widget _stackWidget() {
return Stack(
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 90,
height: 90,
color: Colors.blue,
),
Container(
width: 80,
height: 80,
color: Colors.green,
),
],
);
}
}
效果如下:
如果加入属性 alignment: AlignmentDirectional.bottomEnd, 效果如下:
AlignmentDirectional支持坐标定位,例如添加:AlignmentDirectional(6, 6),效果如下:
设置属性 fit: StackFit.expand, 最后一个子控件会撑满整个Stack,如下:
最后一个子控件是绿色的,所以绿色的就占满了整个Stack,虽然设置了宽高都是80,但是已经没有效果了。
3. Positioned
用来在Stack中辅助子控件定位的组件,一般在子控件超过3个时使用。
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离。
Widget _positionedWidget() {
return Stack(
children: <Widget>[
Positioned(
top: 100,
child: Container(
color: Colors.green,
child: Text('子控件1'),
),
),
Positioned(
top: 200,
right: 100,
child: Container(
color: Colors.red,
child: Text('子控件2'),
),
),
Positioned(
left: 100,
child: Container(
color: Colors.blue,
child: Text('子控件3'),
),
),
],
);
}
效果如下:
Widget _positionedWidget() {
return Stack(
children: <Widget>[
Positioned.fill(
child: Container(
color: Colors.grey,
),
),
Positioned(
top: 100,
left: 0,
right: 0,
child: Container(
color: Colors.green,
child: Text('子控件1'),
),
),
Positioned(
top: 200,
right: 100,
child: Container(
color: Colors.red,
child: Text('子控件2'),
),
),
Positioned(
bottom: 0,
right: 0,
left: 0,
child: Container(
color: Colors.blue,
child: Text('子控件3'),
),
),
],
);
}
4. 实现一个头像布局
import 'package:flutter/material.dart';
class StackPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stack Page'),
),
body: _headStack(),
)
Widget _headStack() {
return Stack(
alignment: Alignment.bottomCenter,
// alignment: FractionalOffset(0.5, 0.89),
children: <Widget>[
Positioned(
child: CircleAvatar(
backgroundImage: NetworkImage(
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1431065488,2677808608&fm=26&gp=0.jpg'),
radius: 100,
),
),
Positioned(
bottom: 20,
child: Container(child: new Text('NickName')),
),
],
);
}
}
效果如下图: