上一篇文章我们已经完成了发现页面的搭建,下一步我们实现微信的我的页面
我的页面

在着手开发我的页面之前,先新建一个discover目录,将发现页面相关的文件统一挪动到这个目录下。这里会发现AndroidStudio一个比较特别的地方,新建一个目录后,挪动了的文件不需要重新导入头文件。AndroidStudio会在需要的地方自动补全路径。这点感觉还是蛮智能的。 
设置APP启动默认展示我的页面
这个设置在上一篇文章开发发现页面的时候也说过了,就是修改rootPage.dart文件里_currentIndex的值。 
布局右上角的拍照按钮
观察这个右上角的拍照按钮,会发现上下拖动列表的时候,这个拍照按钮的位置是不会发生变化的。意思是拍照按钮和列表是同级的关系,不是父子控件的关系。所以这里的布局我们可以使用Stack来实现,ListView放在底下,这个拍照按钮放在上面。布局的方式多种多样,只要是能实现需求效果的都是可行的。这个flutter的UI布局有时候写着写着就会发现括号对不上,使用command + option + L也不管用,依然对不齐,这对于某些强迫症的人看起来是真的挺难受的,下图里都还是我一行一行调整了之后的。 
实现ListView的普通cell部分
首先作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发交流群:编程大鑫,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)
我的页面的ListView的头部那个cell明显和它其他的cell不同,其他的cell跟我们上一篇文章里开发的discover_cell基本上是类似的,所以可以直接拿过来使用。做过iOS开发的都知道,tableView等滚动视图作为控制器的根视图的时候,顶部都会有一个间距,在flutter里面也有这样的情况,如果需要干掉,就需要将我们的ListView包装在一个MediaQuery.removePadding() 里面,然后设置它的属性removeTop: true 。这样就可以去掉顶部的间距了。完整代码如下: 
此时APP显示如图:

实现ListView的头部cell
可以看到我们的_MinePageState的build方法已经够长了,所以关于头部cell的代码我们可以封装为一个方法写在其他的地方。 
关于头部cell这里除了布局稍微复杂了一些之外,就只有给图片加圆角是没有讲过的。要设置圆角图片的话,就不能使用Image类了。需要使用到BoxDecoration 类,它可以设置圆角半径borderRadius 和图片image ;完整代码如下: 
APP显示效果如图:

我的页面就这样完成了。发现页面和我的页面这两个页面主要是对布局的灵活运用,都还是比较简单的。
通讯录页面
接下来实现通讯录界面,这节课先只实现到下图这样,边上的索引下节课再实现。

设置APP启动默认展示通讯录页面
这一步已经讲过2次了,就不再贴图了…
设置通讯录页面导航栏
导航栏的颜色,我们修改了好几次了。这个颜色可以放在一个const.dart的公用文件里。以后统一使用这个颜色,也方便以后统一修改。 
然后是通讯录页面的导航条,除了标题之外,右侧还有一个添加好友的按钮,可以使用AppBar的title实现一个复杂的导航条,但其实没那个必要。AppBar提供了一个actions属性,这个属性就是展示在导航条右侧的,直接使用这个actions就可以了。代码如下: 
实现通讯录列表cell
通讯录列表cell可以使用一种cell来完成,也可以使用两种不同的cell来完成,如果使用一种cell的话,代码里面需要判断的逻辑就会有点多。所以我这里推荐使用两种cell来完成。第一种就是头部的4个cell,这几个属于一类,我们使用类_FriendLocalCell 来表示,而其余的都是属于好友cell属于一类,用类_FriendNetworkCell 表示。关于这两种cell我们暂时先不新建文件存放,直接在friends_page.dart文件中写。
实现_FriendLocalCell
这一类cell主要是用来展示当前列表头部的几个cell的,这几个cell的图片都是从本地加载的。从效果图上可以看出,这个cell只需要title,和imageName这两个必传参数就够了。然后是关于布局。最外层使用一个Row进行左右布局,左侧使用一个能显示圆角的图片。右侧再用一个Column进行上下布局,将文本和底部的分隔线上下排列。这里主要有一个地方没有讲到过,就是在flutter中获取屏幕的宽高,我们会抽成一个方法,放在const.dart文件中。如下图所示: 
_FriendLocalCell 的完整代码如下: 
实现_FriendNetworkCell
关于_FriendNetworkCell ,可能乍一看之下,会觉得应该和上面的cell差不太多。但是实际上还是有那么些区别的。首先flutter的ListView的是没有组的概念的,所以关于组标题就需要我们自己来动手实现了,这里的做法就是,除了上面的_FriendLocalCell 所有的子控件之外,每一个cell都带上一个组标题,然后根据组标题是否有值,来显示或不显示组标题。那么在布局方面,就需要对上面的cell,再包装一个Column,将组标题和头像名称部分包起来。所以当前cell所需要的属性,除了好友的名字name 和头像imageUrl 为必须之外,还需要一个groupTitle 为可选参数。 完整的代码如下: 
准备数据模型
同样的,数据我们也分为两种,一种我们就叫作通讯录,使用AddressBook 来表示。另一种叫好友用Friends 表示。我们将好友列表用到的数据模型都放在新的文件friends_data.dart文件中。
准备AddressBook 模型数组
这个模型数组,可以直接根据我们在效果图上看到的东西,生成对应的模型,和数组就好了。完整代码如下: 
准备Friends 模型数组
这里的数据源已经准备好了,我们只需要根据数据源创建出对应的模型。这个数组是好友数组,有需要的可以自行前往下载。 
实现部分通讯录页面
现在我们的视图和数据都已经准备好了。接下来就是直接使用了,我们之前在发现页面使用ListView的方式,没有使用builder,是直接使用的方式,就跟我们在iOS中的cellForRow方法中每次创建一个新的cell的方式一样,cell没有重复利用。而今天我们使用builder的这种方式,就是cell被放入缓存池中被重复利用的方式。使用ListView.builder() 的方式,需要传入两个参数,一个是itemCount元素的个数。一个是itemBuilder,类似于cellForRowAtIndexPath方法,需要我们创建cell并返回。完整的代码如下: 
这里再说一下对datas进行排序的地方。这个方法initState() 有一个@override修饰,意思就会重写父类的方法,而且这个方法应该是调用的比build要早的。这样才能保证展示数据的时候,数据是已经经过排序过的。而这个排序的方法,其实跟iOS中的sortedArrayUsingComparator: 排序也非常的像,传入一个代码块的方式。所以有开发经验的同学,会发现真的有些东西,各个平台都是通用的,学起来也会更快更容易上手。最后APP的显示如下图:

|