文章中贴出的XML代码你可以直接从git下载并且运行查看效果,git下载地址
这篇带给大家的是对闲鱼app搜索结果页面的布局分析。这类布局的特点是瀑布流宫格布局,也可能设计多种不同的Cell(模板),先上图,如下:
从图片中可以看出如下几个点。
- 宫格布局(严格来说可以说是
瀑布流布局
)。 - 每行显示两个Cell
- 共有三种不同的Cell
- 有些Cell会横跨两列。比如
细选
那个Cell
上面的是大体布局。下面分别分析不同Cell的布局分析
Cell-1(商品布局)
商品信息Cell整体属于自上而下布局。
- 顶部的是商品的图片,并且是按照1:1比例显示。
- 商品名称。并且最多显示一行
- 商品价格等信息
- 用户和位置等信息。并且
信用
的信息显示在右边,头像的右下角还有一个绿色小点。 - 包邮、全新等信息。
下面一一进行分析。
-
商品图片的显示。
<!-- 商品图片,并且按照1:1的比例来显示 --> <ratio-panel ratio="1" background-color="gray"> <image url="{{cover}}" /> </ratio-panel> 复制代码
使用
ratio-panel
提供1:1比例的布局。 -
商品名称显示。
<!-- 商品名称 --> <lable text="{{name}}" font-size="14" font-color="444444" lines="1" /> 复制代码
-
商品价格等信息。
价格信息本来是可以使用lable的富文本方式来显示的,但是lable的富文本的内容是靠底部显示的。但是这里需要垂直居中来显示。那么只有使用
stack-panel
才能满足要求了<!-- 水平布局,并且垂直方向居中显示 --> <stack-panel is-horizon="true" align-items="2"> <!-- 商品价格 --> <lable text="¥" font-color="FB2A35" font-size="12" /> <lable text="{{price}}" font-color="FB2A35" font-size="16" /> <!-- 想要数量 --> <lable text="{{want+'人想要'}}" font-color="gray" font-size="11" space-before="5" /> </stack-panel> 复制代码
stack-panel
的align-items
属性是关键,决定了垂直方向是居中显示的。
- 用户和位置等信息。并且
信用
的信息显示在右边,头像的右下角还有一个绿色小点。<!-- 用户信息 水平布局,并且垂直方向居中布局--> <stack-panel data-path="user" is-horizon="true" space="5" align-items="2"> <!-- 头像 --> <dock-panel size="25" corner-radius="5" clips-bounds="true"> <image background-color="gray" url="{{headIcon}}" /> <!-- 右下角显示绿色小点 --> <panel size="8" background-color="49C856" dock-panel.horizal="2" dock-panel.vertical="2" border-color="white" border-width="2" corner-radius="4" /> </dock-panel> <!-- 用户位置信息 --> <lable text="{{location.name}}" font-color="gray" font-size="10" /> <!-- 信用显示在右边 --> <lable text="芝麻信用|极好" font-color="2EC5BE" font-size="10" flex-grow="1" text-align="2" /> </stack-panel> 复制代码
- 信用信息显示在右边。关键代码是
flex-grow="1" text-align="2"
。这段代码的意思是该lable
占用右边的所有剩余空间,并且文本靠右显示。 - 用户右下角的绿色小点。关键代码是
dock-panel.horizal="2" dock-panel.vertical="2"
。
- 信用信息显示在右边。关键代码是
-
包邮、全新等信息
包邮、全新等信息的显示比较特殊,显示在顶部图片的左下角,并且在x和y方向上分别都偏移了一段距离。
GIC
并没有提供可以偏移的布局面板,但是提供了transforms
功能。因此这里就依靠transforms
来实现了。另外,信息是显示图片上,并且显示在左下角。那么只能采用
dock-panel
布局了。并且和图片存在于同一个dock-panel
中。<!-- 商品图片,并且按照1:1的比例来显示 --> <ratio-panel ratio="1" background-color="gray"> <dock-panel> <!-- 图片 --> <image url="{{cover}}" /> <!-- 全新和包邮图标 --> <stack-panel dock-panel.horizal="0" dock-panel.vertical="2" space="2" is-horizon="true"> <transforms> <!-- x和y方向偏移 --> <translate x="10" y="8" /> </transforms> <!-- 全新图标 --> <if condition="{{ isNew }}"> <dock-panel background-color="FB2A35" size="30 16" corner-radius="3"> <lable text="全新" font-size="10" font-color="white" /> </dock-panel> </if> <!-- 包邮图标 --> <if condition="{{ baoyou }}"> <dock-panel background-color="2F9AFE" size="30 16" corner-radius="3"> <lable text="包邮" font-size="10" font-color="white" /> </dock-panel> </if> </stack-panel> </dock-panel> </ratio-panel> 复制代码
全新
和包邮
的图标并不是每个cell都有的,因此使用if指令
来显示。
Cell-2(标签)
上面的cell的布局区别于商品信息cell。这个cell的布局难点在于三个头像的布局。这里面使用panel
来布局,并且使用postion
来实现在水平方向的偏移布局。
<panel>
<for data-path="users">
<image size="20" url="{{headIcon}}" corner-radius="10" position="{{ 13*$index+' 0' }}" />
</for>
</panel>
复制代码
可以看到,每个
image
的大小为20,设置了10的圆角,这样就成为一个圆形头像。然后每个图片在x方向
进行偏移13*$index
。这样就形成一个部分重叠交集的布局效果了。
Cell-3(筛选)
这个cell的布局就简单了。上面是`title`,下面是一个每行4列的`宫格布局`面板。
-
title
的布局。左右两边分别有一根线,中间是一个
lable
。<stack-panel space-before="20" is-horizon="true" align-items="2" space="10" justify-content="1"> <panel size="30 1" background-color="light-gray" corner-radius="0.5" /> <lable text="细选" font-size="16" font-color="111111" /> <panel size="30 1" background-color="light-gray" corner-radius="0.5" /> </stack-panel> 复制代码
-
宫格布局
<grid-panel columns="4" column-spacing="15" space-before="10" row-spacing="15" space-after="20"> <for> <dock-panel background-color="E1E3E9" height="35" corner-radius="5"> <lable text="{{}}" font-size="14" font-color="333333" /> </dock-panel> </for> </grid-panel> 复制代码
整体布局
上面列出了三种cell的布局方式。每个cell对应一个template
。并且使用collection-view
来实现瀑布流布局。
另外,Cell3(筛选)的Cell需要跨两列显示。只需要设置collection-view
的column-span
附加属性即可。
<collection-view columns="2" row-spacing="10" content-inset="10" background-color="F0F2F8">
<section>
<for data-path="items">
<!-- 使用数据绑定的方式来确定每个cell对应的跨列数 -->
<list-item corner-radius="5" background-color="white" collection-view.column-span="{{ (type==3?3:1) }}">
<!-- 使用数据绑定的方式动态选择不同的模板显示 -->
<template-ref t-name="{{ this.typeToTemplateName(type) }}" />
</list-item>
</for>
</section>
</collection-view>
复制代码
以上的布局代码就是整个闲鱼app搜索结果界面的布局代码。总共才100多行xml代码,比起传统的采用UITableViewCell
的开发方式,不仅在开发效率还是代码可读性上面都有极大的优势。
另外,你可以在运行demo的时候旋转屏幕,你会发现所有的布局都会自动重新布局。而这个过程你甚至连一行代码都不用写。