-
Notifications
You must be signed in to change notification settings - Fork 207
教你构建瀑布流 Step4
完整Demo:WaterfallViewDemo.lua
WaterfallView是MomoLua中对瀑布流布局的封装,继承自CollectionView,相关adapter和layout也都继承自CollectionView相关的adapter和layout。他的使用包括WaterfallView、WaterfallLayout和WaterfallAdapter三个部分。其中WaterfallView决定整个瀑布流布局的显示位置,大小。WaterfallLayout指定adapter中每个视图之间的间隔,大小。Adapter说明数据(Data)和单元视图(ItemView)的绑定关系,以及每个单元视图(ItemView)的渲染方式。整个实现流程可参考TableView、CollectionView的相关思路。
WaterfallView决定整个瀑布流布局的显示位置,大小。此处将介绍其初始化及常用事件和方法。
-------------------------初始化WaterfallView-----------------------------
W = System:screenSize():width()
collectionView = WaterfallView(true, true)
:width(MeasurementType.MATCH_PARENT)
:height(MeasurementType.MATCH_PARENT)
:bgColor(Color(255, 255, 0, 0.5))
:useAllSpanForLoading(true)--加载动画是否占用一行,默认不占用
:showScrollIndicator(true)--显示滑动指示器
--下拉刷新事件回调
collectionView:setRefreshingCallback(
function()
print("开始刷新")
System:setTimeOut(function()
--2秒后结束刷新
print("结束刷新了")
collectionView:stopRefreshing()
end, 2)
end)
--上拉加载事件回调
collectionView:setLoadingCallback(function()
print("开始加载")
System:setTimeOut(function()
--2秒后结束加载
print("结束加载")
collectionView:stopLoading()
--已加载全部
collectionView:noMoreData()
end, 2)
end)
--开始滑动的回调事件
collectionView:setScrollBeginCallback(function()
print("开始滑动")
end)
--滑动中的回调事件
collectionView:setScrollingCallback(function()
--print("滑动中")
end)
--结束滑动的回调事件
collectionView:setScrollEndCallback(function()
print("结束滑动")
end)
--初始化WaterfallLayout,具体实现稍后会介绍
collectionLayout = initWaterfallLayout()
collectionView:layout(collectionLayout)
--adapter初始化方法,具体实现稍后会介绍
adapter = initAdapter()
collectionView:adapter(adapter)
在以上代码中,我们新建一个WaterfallView,其构造方法中2个参数控制是否刷新或加载,并设置其指示器显示以及滑动监听等属性和方法。 相关属性及方法如下:
addHeaderView(View view) | 添加头布局 |
removeHeaderView() | 移除头布局 |
showScrollIndicator(boolean b) | 是否显示滑动指示器 |
useAllSpanForLoading(boolean b) | 加载动画是否占用一行,默认不占用 |
setRefreshingCallback(func callback) | 设置下拉刷新回调 |
setLoadingCallback(func callback) | 设置上拉加载回调 |
setScrollBeginCallback(func callback) | 设置开始滑动回调 |
setScrollingCallback(func callback) | 设置滑动中回调 |
setScrollEndCallback(func callback) | 设置结束滑动回调 |
adapter(Adapter adapter) | 绑定适配器 |
WaterfallLayout指定adapter中每个视图(ItemView)之间的间隔大小。
---------------------------初始化WaterfallLayout----------------------------
collectionLayout = WaterfallLayout()
collectionLayout:itemSpacing(5)--间隔大小
:lineSpacing(5)
:spanCount(2)
collectionView:layout(collectionLayout)
adapter适配器的说明及其关键方法使用类似于TableView的adapter,它作为一个中间类来协助WaterfallView完成对于子View的创建和赋值操作。可前往TableView了解更多详细。 用法如下:
---------------------------初始化WaterfallAdapter----------------------------
local function initAdapter()
adapter = WaterfallAdapter()
adapter:sectionCount(function()
return 1
end)
-----------------------------设置header----------------------------------
adapter:initHeader(function(header)
header.contentView:bgColor(Color(0, 0, 255, 0.3))
header.textLabel = Label():setGravity(Gravity.CENTER):width(MeasurementType.MATCH_PARENT):height(MeasurementType.MATCH_PARENT):lines(0):textAlign(TextAlign.CENTER)
header.contentView:addView(header.textLabel)
end)
adapter:fillHeaderData(function(header, section, row)
header.textLabel:text('我是头布局')
end)
adapter:headerValid(function(section)
return true
end)
adapter:heightForHeader(function(section)
return 100
end)
-----------------------------设置子view个数-------------------------------
adapter:rowCount(function(section)
if datas == nill or #datas == 0 then
return 0;
else
return #datas;
end
end)
--------------------------------设置cell高-------------------------------
--设置对应子view的高
adapter:heightForCell(function(section, row)
return datas[row].height
end)
-------------------------------子view类型--------------------------------
--返回当前位置子view的类型标识
adapter:reuseId(function(section, row)
return "CellId"
end)
-------------------------------创建子view--------------------------------
adapter:initCellByReuseId("CellId", function(cell)
cell.userView = LinearLayout(LinearType.VERTICAL)
:setGravity(Gravity.CENTER)
--头像
cell.imageView = ImageView():width(50):height(50):cornerRadius(45)
:priority(1):bgColor(Color(255, 0, 0, 0.5))
:setGravity(Gravity.CENTER)
cell.userView:addView(cell.imageView)
--昵称
cell.nameLabel = Label():fontSize(14):textColor(Color(0, 0, 0, 1))
:text("昵称"):setGravity(Gravity.CENTER)
:marginTop(5)
cell.contentView:bgColor(Color(255, 255, 255, 1))
:cornerRadius(5)
cell.userView:addView(cell.nameLabel)
cell.contentView:addView(cell.userView)
end)
--------------------------将子view与数据进行绑定赋值-------------------------
adapter:fillCellDataByReuseId("CellId", function(cell, section, row)
cell.nameLabel:text(datas[row].name)
end)
--cell点击事件
adapter:selectedRowByReuseId("CellId", function(cell, section, row)
print("点击了cell", row .. datas[row])
end)
--cell被滑出屏幕可见区域的回调
adapter:cellDidDisappear(function(cell, section, row)
print("cell不见了", row)
end)
--cell出现在屏幕可见区域的回调
adapter:cellWillAppear(function(cell, section, row)
print("cell出现了", row)
end)
--头布局header被滑出屏幕可见区域的回调
adapter:headerDidDisappear(function()
print("头布局header不见了")
end)
--头布局header出现在屏幕可见区域的回调
adapter:headerWillAppear(function()
print("头布局header出现了")
end)
return adapter
end
上述代码我们可以看到基本与TableView的adapter使用一样。相关方法可参考TableView使用教程。对于头布局header,我们以下几个常用方法:
headerDidDisappear(function()) | 头布局header被滑出屏幕可见区域的回调 |
headerWillAppear(function()) | 头布局header出现在屏幕可见区域的回调 |
--初始化适配器
--创建子view
adapter:initCell(function(cell)
end)
--将子view与数据进行绑定赋值
adapter:fillCellData(function(cell, section, row)
end)
--cell点击事件
adapter:selectedRow(function(cell, section, row)
end)
return adapter
【注】 区分reuseId的方法不能与不区分reuseId的方法同时使用,如使用initCellByReuseId方法初始化单元视图时就不可再使用initCell方法。
以上代码完成了adapter初始化,之后调用adapter方法实现适配器绑定即可完成瀑布流布局的一个简单实现。 总结:TableView(列表布局)、CollectionView(网格布局)、WaterfallView(瀑布流布局)整体实现思路上基本一致,包括其adapter的实现方法。
上述例子datas的数据格式:
datas = {
{
name = "苹果",
height = 140
},
{
name = "葡萄",
height = 100
},
{
name = "西瓜",
height = 130
},
{
name = "草莓",
height = 118
},
{
name = "菠萝",
height = 190
},
{
name = "香蕉",
height = 100
},
{
name = "芒果",
height = 120
},
{
name = "猕猴桃",
height = 150
},
{
name = "橘子",
height = 180
},
{
name = "哈密瓜",
height = 200
},
}