使用 FutureProvider 搞定个人主页异步请求的状态管理
前言
好久没有讲界面的内容了,本篇做一个个人主页的头部区域,一方面是讲一下 Flutter 的 Stack 层叠组件的用法,另一方面是 Provider 的 FutureProvider 的使用。
界面分析
拿到界面,我们首先分析一下界面的结构,头部这部分从下到上由如下内容组成:
底图和头像
底部 Banner 图:在最底部;
头像:包括头像图片下的背景圆(或边框),叠加在底部 Banner 上;
用户名称、级别、工作信息(头衔及公司)及个人介绍等个人信息:在底图和头像下方。
关注、关注者和掘力值等统计数据:在用户信息下方。
返回按钮:返回按钮在整个页面的顶层,以便可以随时点击返回。
得到我们页面的布局结构如下图所示。其中头像和 Banner
因为重叠了,需要使用一个 Stack
组件包裹,即蓝色的区域。
组件结构
确定好了布局,我们再来确定使用什么样的组件,各个布局区域对应的组件如下:
返回按钮:
IconButton
,使用一个返回图标按钮,点击后返回上一页。Banner:使用
CachedImageNetWork
,以便可以加载网络图片。头像:使用一个
Stack
,底部是实现边框的圆形Container
,上层是圆形头像,使用Container
+CachedImageNetwork
实现。 同时整个头像区域使用Positioned
绝对位置布局,保持左侧和返回按钮对齐,然后由有一半区域叠加在Banner
上。个人信息区域:使用列布局
Column
排布各项信息,然后昵称和等级使用行布局Row
。统计信息区域:使用行布局
Row
排布各个统计数据,统计数据本身使用Column
布局数字和数据项名称。
整个页面使用的是 CustomScrollView
,然后再用 Stack
包裹整个页面和返回按钮,并将返回按钮使用 Positioned
绝对定位保持在左上角。最后的组件树如下(省略了Container
组件)。
重点介绍一下 Stack
和 Postioned
组件。Stack
组件分为Stack
和 IndexedStack
。IndexedStack
其实就是一个有序的 Stack
,可以通过控制当前序号显示第几层的界面。而 Stack
的 children 是一组组件,使用的是堆叠排序,次序在后面的层级越高,显示层级也更靠前(后进先出原则)。通过这种方式可以达到多个界面层叠显示的目的。
Positioned
组件是专门用于 Stack
的子组件,用于控制 Stack
的子组件相对于 Stack
的位置,可以通过 left
,top
,right
,bottom
和 height
属性来控制子组件位置。
具体规则如下:
如果
top
属性不为空,就会将组件的顶部定位到Stack
组件顶部距离top
单位的位置。其他如left
,right
和bottom
的机制类似。如果
top
和bottom
都不为空,那么该组件就会按照约束条件限制在 Stack 中布局的高度(固定距离上下边界的位置)。left
和right
不为空的时候就会限制宽度约束。如果
top
和bottom
只有一个不为空,那么就可以指定高度。如果left
和right
只有一个不为空,那么就可以指定宽度。left
、right
和width
三个属性至少有一个不为空;top
,bottom
和height
也一样。
例如我们要定位头像组件的位置,我们可以设置左边距离为 20,然后垂直方向距离为 Banner
图片的高度减去头像组件自身高度的一半(等于头像半径加上边框尺寸)使得头像与 Banner
图片重叠。
接下来就是其他代码实现了,这里就只贴一下顶层组件的代码,具体实现细节可以去这里下载代码(界面文件为:personal_homepage.dart
):状态管理代码。
接口数据获取
从浏览器开发者工具抓出个人主页接口,接口返回的数据项很多,摘抄我们需要的数据格式如下:
然后就是基于这个数据构建实体类了,即源码里的personal_entity.dart
文件。对应的接口请求服务如下:
Future 状态管理
Provider 的状态管理为异步操作 Future 对象提供了一种更为快捷简便的方式,那就是 FutureProvider。还记得我们的动态详情页面,因为需要先请求数据才能刷新界面,我们将详情页面改成了 StatefulWidget,以便在 initState 中请求数据。
而使用了 FutureProvider
后,可以将请求放到 FutureProvider
。FutureProvider
会发起该异步操作,并且在 Future
异步操作完成后会自动通知下级组件,可以不需要使用 StatefulWidget
也能完成网络请求。FutureProvider
的使用方法和 ChangeNotiferProvider
类似,如下所示,其中 initialValue
是初始数据,可以是 null
:
在这里我们就可以使用 FutureProvider
来完成个人信息请求后自动刷新界面,相关代码如下所示:
运行结果
总结
本篇仿做了个人主页顶部部分界面,通过界面我们分析了布局、组件层级,重点介绍了 Stack
组件和 Positioned
组件的使用,以及使用FutureProvider
自动完成异步操作后通知界面刷新,从而简化我们的页面代码,比如无需使用 initState
和编写状态管理类。每个人实现界面的方式不同,但思路都是一致的:
分析 UI 设计稿布局;
划分代码层级大的布局块。
细化布局块,构建 UI 组件树。
抽取界面中可能共用的部分,提高复用性,例如本篇中的统计数据,这块就具有一定的通用性,是可以单独抽出来组件的。
完整源码已上传至: Provider 状态管理相关代码。
版权声明: 本文为 InfoQ 作者【岛上码农】的原创文章。
原文链接:【http://xie.infoq.cn/article/241f027033bd233acf7e80fe5】。文章转载请联系作者。
评论