[toc]

简介

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

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

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

flutter系列之:flutter中常用的Stack layout详解的更多相关文章

  1. flutter系列之:flutter中常用的GridView layout详解

    目录 简介 GridView详解 GridView的构造函数 GridView的使用 总结 简介 GridView是一个网格化的布局,如果在填充的过程中子组件超出了展示的范围的时候,那么GridVie ...

  2. flutter系列之:flutter中常用的ListView layout详解

    目录 简介 ListView详解 ListView中的特有属性 ListView的构造函数 ListView的使用 总结 简介 ListView是包含多个child组件的widget,在ListVie ...

  3. flutter系列之:flutter中常用的container layout详解

    目录 简介 Container的使用 旋转Container Container中的BoxConstraints 总结 简介 在上一篇文章中,我们列举了flutter中的所有layout类,并且详细介 ...

  4. Android总结篇系列:Activity中几个主要函数详解

    Activity作为Android系统中四大基本组件之一,包含大量的与其他的各大组件.intent.widget以及系统各项服务等之间的交互的函数.在此,本文主要选取实际项目开发中常用的,但完全理解又 ...

  5. java日志框架系列(7):logback框架Layout详解

    1.Layout layout从字面意思来看就是排版.布局咯. 1.Layout简介 功能:负责把事件转换成字符串.Layout接口的格式化方法doLayout()负责将代表任何类型的事件的转换成一个 ...

  6. flutter系列之:构建Widget的上下文环境BuildContext详解

    目录 简介 BuildContext的本质 BuildContext和InheritedWidget BuildContext的层级关系 总结 简介 我们知道Flutter中有两种Widget,分别是 ...

  7. Windows学习总结(10)——Windows系统中常用的CMD命令详解

    1.ping命令 ping是电脑网络故障诊断中的常用的命令,它的作用是用来检查网络是否通畅或者网络连接速度.我们来看一下PING命令的具体表述. 日常的诊断过程中我们最常用到的就是诊断连接是否通畅. ...

  8. [ES6系列-03]ES6中关于参数相关特性详解(参数默认值与参数解构赋值与剩余参数)

    [原创] 码路工人 大家好,这里是码路工人有力量,我是码路工人,你们是力量. 今天总结一下 ES6 中跟参数相关的内容. 欢迎补充斧正.留言交流. 让我们互相学习一起进步. 1. ES6 参数默认值( ...

  9. Oracle中常用的to_char用法详解

    Oracle函数to_char转化数字型指定小数点位数的用法 to_char,函数功能,就是将数值型或者日期型转化为字符型. 比如最简单的应用: -- 1.0123=>1.0123 SELECT ...

随机推荐

  1. Session会话 Cookie JSTL标签

    Cookie  1) HTTP是无状态协议(连接结束后就自动断开),服务器不能记录浏览器的访问状态,也就是说服务器不能区分中两次请求是否由一个客户端发出.这样的设计严重阻碍的Web程序的设计.如:在我 ...

  2. idea 生成方法注释

    /* * * @description: * @author: xuetong.yang * @date: $date$ $time$ $params$ * @return: $return$ */ ...

  3. 图论学习笔记·$Floyd$ $Warshall$

    对于图论--虽然本蒟蒻也才入门--于是有了这篇学习笔记\(qwq\) 一般我们对于最短路的处理,本蒟蒻之前都是通过构建二维数组的方式然后对每两个点进行1次深度或者广度优先搜索,即一共进行\(n\)^2 ...

  4. 输出以二叉树表示的算术表达式(严6.51)--------西工大noj

    题解 这道题目说的很诡异,其实没有什么把括号补上....仅仅是先序读入,然后中序输出就行了 代码 #include <stdio.h> #include <stdlib.h> ...

  5. 2022-7-9 第五小组 潘堂智 html学习笔记

    什么是 HTML? HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种标记语言 (ma ...

  6. Collection集合概述和集合框架介绍

    集合概述 集合:集合是java中提供的一种容器,可以用来存储多个数据 集合和数组既然都是容器,他们有什么区别? 1.数组的长度是固定的,集合的长度是可变的 2.数组中存储的是同一类型的元素,可以存储基 ...

  7. 1000-ms-maven相关问题

    一.Maven有哪些优点和缺点 优点如下: 简化了项目依赖管理: 易于上手,对于新手可能一个"mvn clean package"命令就可能满足他的工作 便于与持续集成工具(jen ...

  8. Percona XtraBackup 8.0.26使用说明

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 Percona XtraBackup特性说明 Percona Xtrabacku ...

  9. 解决zlibrary注册后,再次登录提示密码错误的问题

    很多小伙伴注册后,再登录提示电子邮件或密码错误,但是可以确认账号密码都是正确的,这种应该怎么处理呢? 其实这种问题有两种处理方式, 首先使用 https://find.looks.wang/ 检测可以 ...

  10. C++11实现的数据库连接池

    它什么是? 数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个:类似的还有线程池. 为什么要用? 一个数据库连接对象均对应一个物理数据库连接, ...