层叠布局适用于子视图叠放一起,且位置能够相对于父视图边界确认的情况。
<!--more-->
比如,可用于图片上加文字,按钮上加渐变阴影等等。
Stack
Widget的子视图要么是positioned
,要么是non-positioned
。Positioned
子视图是指使用Positioned
的widget包括起来的子视图,通过设置相对于Stack
的top
、bottom
、left
、right
属性来确认自身位置,其中至少要有一个不为空。
Stack
Widget的大小取决于所有non-positioned
的子视图。non-positioned
的子视图的位置根据alignment
属性确定,(当alignment
为left-to-right
时,子视图默认从左上角开始;当aligment
为right-to-left
时,子视图从右上角开始;)。
Positioned常用属性如下:
使用代码如下:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var stack = new Stack(
alignment: Alignment.bottomRight,
children: [
new Container(
width: 300.0,
height: 300.0,
color: Colors.orange,
),
new Container(
width: 200.0,
height: 200.0,
color: Colors.green,
),
new Text(
'alignment bottomRight',
style: TextStyle(color: Colors.white, fontSize: 21),
)
],
);
return MaterialApp(
title: 'StackView Widget',
home: Scaffold(
appBar: new AppBar(
title: new Text('StackView Widget'),
),
body: Center(
child: stack,
),
),
);
}
}
效果如下:
<center>
<figure>
<img src="https://inews.gtimg.com/newsapp_ls/0/13816653145/0.png" style="width:200px" />
<img src="https://inews.gtimg.com/newsapp_ls/0/13816653148/0.png" style="width:200px" />
<img src="https://inews.gtimg.com/newsapp_ls/0/13816653172/0.png" style="width:200px" />
</figure>
</center>
<!-- ![wecom20210727-093838.png](https://inews.gtimg.com/newsapp_ls/0/13816653145/0.png)
从上面的对比,可以看出alignment
的属性,对设置Stack
的子视图的效果
为了方便查看clipBehavior
的效果,需要写一个相对于Stack
超出的子视图,使用Postitioned
Widget,设置top、left为负值即可。
代码如下:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var stack = new Stack(
clipBehavior: Clip.antiAliasWithSaveLayer,
children: [
new Container(
width: 300.0,
height: 300.0,
color: Colors.orange,
),
Positioned(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.green,
),
left: -20,
top: -20),
new Text(
'clip antiAliasWithSaveLayer',
style: TextStyle(color: Colors.white, fontSize: 21),
),
],
);
return MaterialApp(
title: 'StackView Widget',
home: Scaffold(
appBar: new AppBar(
title: new Text('StackView Widget'),
),
body: Center(
child: stack,
),
),
);
}
}
效果如下:
<center>
<figure>
<img src="https://inews.gtimg.com/newsapp_ls/0/13816756422/0.png" style="width:200px" />
<img src="https://inews.gtimg.com/newsapp_ls/0/13816756420/0.png" style="width:200px" />
<img src="https://inews.gtimg.com/newsapp_ls/0/13816756442//0.png" style="width:200px" />
<img src="https://inews.gtimg.com/newsapp_ls/0/13816756419//0.png" style="width:200px" />
</figure>
</center>
<!-- ![wecom20210727-100400.png](https://inews.gtimg.com/newsapp_ls/0/13816756422/0.png)
从上面可以看出clipBehavior
的效果
fit填充方式,fit的expand和loose属性很容易区分,但是loose和passthrough属性的区别需要特别注意。为了容易区分出来不同,这里使用Row
作为的父视图Stack
。
简单的理解,expand是充满父视图;loose是按照子视图的大小来;passthrough则是按照父视图的父视图的约束来。
使用代码如下:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var stack = new Stack(
// alignment: Alignment.bottomRight,
fit: StackFit.passthrough,
children: [
new Container(
width: 300.0,
height: 300.0,
color: Colors.orange,
),
new Container(
width: 200.0,
height: 200.0,
color: Colors.green,
),
new Text(
'StackFit passthrough',
style: TextStyle(color: Colors.white, fontSize: 21),
),
],
);
return MaterialApp(
title: 'StackView Widget',
home: Scaffold(
appBar: new AppBar(
title: new Text('StackView Widget'),
),
body: Center(
child: Row(
children: [Expanded(child: stack)],
),
),
),
);
}
}
效果如下:
<center>
<figure>
<img src="https://inews.gtimg.com/newsapp_ls/0/13816875315/0.png" style="width:200px" />
<img src="https://inews.gtimg.com/newsapp_ls/0/13816875289/0.png" style="width:200px" />
<img src="https://inews.gtimg.com/newsapp_ls/0/13816875303//0.png" style="width:200px" />
</figure>
</center>
<!-- ![wecom20210727-103211.png](https://inews.gtimg.com/newsapp_ls/0/13816875315/0.png)
从上面可以看出,StackFit为passthrough属性时,使用了Row的Expand的布局;StackFit为loose时,使用的是子视图的布局;StackFit为expand时,使用的是Stack的布局。
代码如下:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var stack = SizedBox(
width: 250,
height: 250,
child: Stack(
children: [
Container(
width: 250,
height: 250,
color: Colors.orange,
),
Container(
padding: const EdgeInsets.all(5.0),
alignment: Alignment.center,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black.withAlpha(0),
Colors.black12,
Colors.black45,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
)),
child: const Text('Foreground Text',
style: TextStyle(color: Colors.white, fontSize: 20.0))),
],
),
);
return MaterialApp(
title: 'StackView Widget',
home: Scaffold(
appBar: new AppBar(
title: new Text('StackView Widget'),
),
body: Center(
child: stack,
),
),
);
}
}
效果如下:
<img src="https://inews.gtimg.com/newsapp_ls/0/13816932246/0.png" style="width:200px" />
<!-- ![wecom20210727-104610.png](https://inews.gtimg.com/newsapp_ls/0/13816932246/0.png) -->
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。