共计 3899 个字符,预计需要花费 10 分钟才能阅读完成。
简介
对于古代 APP 的利用来说,为了更加好看,通常会须要用到不同图像的重叠成果,比方在一个 APP 用户背景头像下面增加一个按钮,示意能够批改用户信息等。
要实现这样的成果,咱们须要在一个 Image 下面重叠其余的 widget 对象,flutter 为咱们提供了这样的一个十分不便的 layout 组件叫做 Stack,明天和大家一起来聊一聊 Stack 的应用。
Stack 详解
咱们先来看下 Stack 的定义:
class Stack extends MultiChildRenderObjectWidget
Stack 继承自 MultiChildRenderObjectWidget,示意在 stack 中能够 render 多个 child widget 对象。
因为 Stack 中的 child 是重叠关系,所以须要对 child 进行定位,依据定位的不同 Stack 中的 child 能够分为两种类型,别离是 positioned 和 non-positioned。
所谓 positioned,是指 child widget 被包装在 Positioned 中。什么是 Positioned 呢?
Positioned 是专门用来定位 Stack 中的 child 地位的一个 widget。所以 Positioned 必须用在 Stack 中,并且 Positioned 和 Stack 的门路之间只能存在 StatelessWidget 或者 StatefulWidget 这两种 widget。
如果一个对象被蕴含在 Positioned 中,那么这个对象就是一个 Stack 中的 positioned 对象。
Positioned 中除了封装的 child 之外,还有 6 个属性,如下所示:
const Positioned({
Key? key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
required Widget child,
})
这六个属性别离是 left,top,right,bottom,width 和 height。其中 left,top,right,bottom 别离示意到左,顶,右,底的间隔,这个间隔是绝对 stack 来说的。而 width 和 height 则示意的是 Positioned 的宽度和高度。
事实上,应用 left 和 right 能够定义出 width, 应用 top 和 bottom 能够定义出 height。
如果在一个轴方向的三个值都不存在,那么会应用 Stack.alignment 来定位子元素。
如果六个值都不存在,那么这个 child 就是一个 non-positioned 的 child。
对于 non-positioned 的 child,是通过 Stack 的 alignment 来进行布局的, 默认状况下是按 top left corners 进行布局的。
Stack 的属性
咱们接下来看一下 Stack 中有哪些属性,上面是 Stack 的构造函数:
Stack({
Key? key,
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
@Deprecated(
'Use clipBehavior instead. See the migration guide in flutter.dev/go/clip-behavior.'
'This feature was deprecated after v1.22.0-12.0.pre.',
)
this.overflow = Overflow.clip,
this.clipBehavior = Clip.hardEdge,
List<Widget> children = const <Widget>[],})
能够看到 Stack 中有 alignment,textDirection,fit,overflow 和 clipBehavior 这几个属性。
首先来看 alignment,这里的 alignment 是一个 AlignmentGeometry 对象,次要用来布局 non-positioned children。
AlignmentGeometry 中有两个须要设置的属性,别离是 start 和 y。
start 示意的是横线定位范畴,它的取值比拟奇怪,- 1 示意的是 start side 的边缘地位,而 1 示意的是 end side 的边缘地位。如果取值超过了这个范畴,则示意对应的地位超过了边缘地位。
start 的地位跟 TextDirection 是相关联的,如果 TextDirection 的值是 ltr,也就是说从左到右排列,那么 start 就在最右边,如果 TextDirection 的值是 rtl,也就是说从右到左排列,那么 start 就是在最左边。
有横向地位就有纵向地位,这个纵向地位用 y 来示意,它的失常取值范畴也是 - 1 到 1,当然你也能够超出这个范畴。
为了用户更加不便的应用 AlignmentGeometry,AlignmentGeometry 提供了一些便捷的办法, 如 topStart,topCenter,topEnd 等,大家能够自行选取。
接下来的属性是 textDirection,textDirection 是一个 TextDirection 对象,它有两个值,别离是 rtl 和 ltr, 在解说 alignment 的时候, 咱们曾经提到过 textDirection,它会影响 alignment 中横向的布局。
接下来是 StackFit 类型的 fit 属性,StackFit 有三个值,别离是 loose,expand 和 passthrough。
loose 示意的是一个涣散构造,比方 Stack 规定的 size 是 300×500, 那么它的 child 的宽度能够从 0 -300,child 的高度能够从 0 -500.
expand 示意是一个裁减的成果,比方 Stack 规定的 size 是 300×500, 那么它的 child 的宽度就是 300,child 的高度就是 500.
passthrough 示意传递给 stack 的限度会一成不变的传递给他的 child,不会进行任何批改。
overflow 示意 children 超出展现局部是否会被剪切。不过这个属性曾经是 Deprecated,flutter 举荐咱们应用 clipBehavior 这个属性来代替。
clipBehavior 是一个 Clip 对象,它的默认值是 Clip.hardEdge。其余的几个值还有 none,hardEdge,antiAlias 和 antiAliasWithSaveLayer。
none 示意不进行任何裁剪,hardEdge 的裁剪速度最快,然而精确度不高。antiAlias 速度比 hardEdge 慢一点,然而有润滑的边缘。antiAliasWithSaveLayer 是最慢的,应该很少被应用。
Stack 的应用
有了下面的解说,接下来咱们看一下 Stack 的具体应用。
在咱们这个例子中,咱们在 Stack 中设置一个背景图片,而后在图片上叠加一个文本。
那么应该怎么实现呢?
首先咱们须要设置 Stack 的 alignment 形式,咱们心愿文本和图片的核心重合,也就是说把文字放在图片两头,咱们将 Stack 的 alignment 设置为 Alignment.center。
接下来是一个背景图片,因为原始图片是一个正方形的图片,咱们须要对图片进行裁剪成圆形,这里应用一个十分不便的类 CircleAvatar 来创立圆形的图标:
const CircleAvatar(backgroundImage: AssetImage('images/head.jpg'),
radius: 100,
),
下面的代码可能创立一个半径是 100 的圆。
而后是文本的创立,能够给 Text 设置文本内容和对应的 style:
Text(
'编辑',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
)
而后把 Text 封装在 Container 中,并应用 BoxDecoration 给他指定一个背景:
Container(
decoration: const BoxDecoration(color: Colors.green,),
child: const Text(...
最初将下面的代码组合起来就是咱们最初的 Stack:
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.center,
children: [
const CircleAvatar(backgroundImage: AssetImage('images/head.jpg'),
radius: 100,
),
Container(
decoration: const BoxDecoration(color: Colors.green,),
child: const Text(
'编辑',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
);
运行生成的界面如下:
总结
以上就是 Stack 的应用,通过重叠组件,咱们能够实现很多炫酷的性能。
本文的例子:https://github.com/ddean2009/learn-flutter.git
更多内容请参考 http://www.flydean.com/11-flutter-ui-layout-stack/
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!