简介
对于古代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是300x500,那么它的child的宽度能够从0-300,child的高度能够从0-500.
expand示意是一个裁减的成果,比方Stack规定的size是300x500,那么它的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/
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」,懂技术,更懂你!