Flutter 仿微信价值几个亿的页面
网传微信支付页面的第三方链接一个格子需要广告费 1 一个亿,微信支付页非常适合做功能导航,本篇使用 ListView 和 GridView 模仿了微信支付的页面,同时介绍了如何装饰一个组件的背景和边缘样式。
左侧是微信支付的界面,右侧是开发完成后的效果,图标是从 iconfont 上下载的。首先介绍一下本篇涉及到的组件。
带装饰效果的 Container
实际过程中我们经常会遇到一个容器需要额外的样式,例如圆角,背景色等。在 Flutter 中,对于各种容器都有一个 decoration 的属性,可以用于装饰容器。典型的用法有设置背景色、圆角、边框和阴影等,其中背景色可以使用渐变色。decoration 是一个 Decoration 对象,最常用的是 BoxDecoration,BoxDecoration 的属性如下所示:
其中 color 为使用颜色填充容器,image 为 使用图片作为背景,border 为边框,borderRadius 为边框圆角,boxShadow 为容器阴影,gradient 使用渐变色作为背景,backgroundBlendMode 是指与容器的混合模型,默认是覆盖,shape 是背景形状,默认是矩形。其中背景部分我们一般只会选择一种。这里以上面的绿色圆弧背景为例,还加上了一点点渐变(渐变色支持多个,可以根据需要调节),示例代码如下:
这里设置了边角为圆弧,半径为 4,使用渐变色填充,渐变方向为从顶部中央到底部中央,渐变色有两个。
Row 行布局和 Column 列布局
Row
代表行布局(即子元素按一行排布),Column
代表列布局(即子元素按一列排布)。
ListView 列表组件
列表视图,和之前的一篇一样,只是本篇的用法不同,用于实现整个页面可以按列表的方式进行滚动,直接将各个部分组件放入到列表的children
属性中,而不是使用数组构建列表元素,有点类似滚动视图的用法。
GridView 网格组件
GridView 用于将一个容器按行列划分,可以指定主轴的元素个数(根据滚动方向定),之后自动按总元素的个数分别填充到网格,例如按纵向滚动时,则可以指定行方向一行有多少个网格,每个网格一个元素。超出一行数量后会自动换另一行。最简单的用法是使用 GridView.count
方法构建 GridView
,用法如下:
这里 crossAxisSpacing
是与滚动方向垂直的元素的间距,如按纵向(默认值)滚动,则是横向行元素之间的间距。mainAxisSpacing
是与滚动方向相同的元素的间距。children
即网格中的元素。这里需要注意的是,由于 本例中GridView
是嵌套在 ListView
里面的,两个组件都是纵向滚动,这样会引起冲突导致布局无法满足约束。因此,在这里设置了 shrinkWrap
为 true
和 physics
为NeverScrollableScrollPhysics
,以禁止 GridView
的滚动,从而满足约束。
代码实现
首先来分析布局,所有菜单按钮其实都是一样的布局,可以使用统一的列布局完成菜单按钮,提高复用性。菜单按钮从上到下一次为图标、间距(图标与文字之间)和菜单名称。实现代码如下:
通过传输一个图标名称,菜单名称和可选的字体颜色(顶部区域和其他的文字颜色不同)来实现单个菜单。
其次来看顶部区域,顶部区域只有两个按钮,使用带装饰的容器实现背景的装饰和圆角。再采用行布局将两个菜单按钮在横向均匀排布。同时,使用
Center
布局将两个菜单保持中部居中。这里指定了容器的高度,这是因为从美观上看太矮了不太协调,实际开发要根据 UI 设计稿定。
其他菜单布局都是一样,只是区域标题,菜单数量、菜单内容不同,因此可以统一封装一个通用的方法来构建任意形式的菜单,以及设置区域标题的字体样式、圆角背景等属性。菜单均使用
GridView
实现网格式布局,同时由于菜单布局相同,可以封装一个通用的方法来指定网格一行按钮的数量,按钮字体颜色等属性,实现代码的复用。
ListView
构建完整页面:实际的整个页面很简单,只需要将各个区域放入到ListView
的children
属性即可,从这里也可以看出,将子组件尽可能细化,不但能够提高代码复用性,还可以降低嵌套层级,提高代码的可读性和可维护性。
Mock 数据准备
按钮数据均使用 Mock
数据,这里只是返回一个 List<Map<String, String>>
数组对象,对象里是每个菜单的图标文件名称和菜单名称,下面是金融服务区域的菜单 Mock
方法。
其他待改进的地方:从代码中可以看出,访问按钮的时候是使用
Map
对象的键来访问的,需要使用['name']
或['icon']
来访问,这种方式非常不利于编码,而且很容易拼写错误。因此,实际使用中应当将Json
对象(即Map
)转换为实体类,这样就可以通过访问实体类的属性来设置菜单的参数,实际维护起来更为方便。
结语:Flutter 提供的基础 UI 组件库能够满足绝大部分复杂页面布局,通过各种布局组件的组合即可完成。因此,熟悉基础的布局组件的特性十分重要。同时,需要注意组件的拆分和抽离完成子组件的封装,提高复用性的同时也避免了嵌套层级过深的问题。
版权声明: 本文为 InfoQ 作者【岛上码农】的原创文章。
原文链接:【http://xie.infoq.cn/article/dba0099b261b677dcf9d8f4de】。文章转载请联系作者。
评论