简介

对于古代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/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」,懂技术,更懂你!