Skip to content

CollectionView使用教程 Step3

zhangxin-it edited this page Feb 25, 2020 · 3 revisions

CollectionView(网格布局)

完整Demo:CollectionViewDemo.lua

CollectionView是MomoLua中对网格布局的封装,他的使用包括CollectionView、CollectionViewLayout和Adapter三个部分。其中CollectionView决定整个网格布局的显示位置,大小。CollectionViewLayout指定adapter中每个视图之间的间隔,大小。Adapter说明数据(Data)和单元视图(ItemView)的绑定关系,以及每个单元视图(ItemView)的渲染方式。

一、CollectionView

CollectionView决定整个网格布局的显示位置,大小。此处将介绍其初始化及常用事件和方法。

--初始化CollectionView
local W = window:width()
local H = window:height()
collectionView = CollectionView(true, true)
        :width(MeasurementType.MATCH_PARENT)
        :height(H - 100)
        :scrollDirection(ScrollDirection.VERTICAL)--竖直方向滑动
        :showScrollIndicator(true)--是否显示滑动指示器
        :bgColor(Color(255, 255, 0, 0.5))
--下拉刷新事件回调
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)
--初始化CollectionViewLayout,具体实现稍后会介绍
collectionLayout = initCollectionViewLayout()
collectionView:layout(collectionLayout)
--adapter初始化方法,具体实现稍后会介绍
adapter = initAdapter()
collectionView:adapter(adapter)

在以上代码中,我们新建一个CollectionView,其构造方法中2个参数控制是否刷新或加载,并设置CollectionView滑动方向、指示器显示以及滑动监听等属性和方法。 相关属性及方法如下:

scrollDirection(ScrollDirection direction) 设置滑动方向(水平或竖直)
showScrollIndicator(boolean b) 是否显示滑动指示器
setRefreshingCallback(func callback) 设置下拉刷新回调
setLoadingCallback(func callback) 设置上拉加载回调
setScrollBeginCallback(func callback) 设置开始滑动回调
setScrollingCallback(func callback) 设置滑动中回调
setScrollEndCallback(func callback) 设置结束滑动回调
adapter(Adapter adapter) 绑定适配器
至此CollectionView的初始化操作基本完成。

二、CollectionViewLayout

CollectionViewLayout指定adapter中每个视图(ItemView)之间的间隔大小、行数或列数。

--初始化CollectionViewLayout
collectionLayout = CollectionViewLayout()
collectionLayout:itemSpacing(5)--间隔大小
                :lineSpacing(5)
--竖直滑动代表显示列数;水平滑动代表显示行数
collectionLayout:spanCount(3)
collectionView:layout(collectionLayout)

三、CollectionViewAdapter

adapter适配器的说明及其关键方法使用类似于TableView的adapter,它作为一个中间类来协助CollectionView完成对于子View的创建和赋值操作。可前往TableView了解更多详细。 用法如下:

--初始化适配器
local function initAdapter()

    adapter = CollectionViewAdapter()
    
    adapter:sectionCount(function()
        return 1
    end)

    -----------------------------设置子view个数---------------------------------------
    count = 20
    adapter:rowCount(function(section)
        return count
    end)
    ------------------------------设置cell宽高----------------------------------------
    --根据类型标识设置对应子view的宽高
    adapter:sizeForCellByReuseId("CellId", function()
        return Size(100, 100)
    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))
        cell.userView:addView(cell.nameLabel)
        cell.contentView:addView(cell.userView)
    end)
    --------------------------将子view与数据进行绑定赋值----------------------------------
    adapter:fillCellDataByReuseId("CellId", function(cell, section, row)
        cell.nameLabel:text("盖世英雄")
    end)
    --cell点击事件
    adapter:selectedRowByReuseId("CellId", function(cell, section, row)
        print("点击了cell", row)
    end)
    --cell被滑出屏幕可见区域的回调
    adapter:cellDidDisappear(function(cell, section, row)
        print("cell不见了", row)
    end)
    --cell出现在屏幕可见区域的回调
    adapter:cellWillAppear(function(cell, section, row)
        print("cell出现了", row)
    end)

    return adapter
end

【注】 上述代码我们可以看到基本与TableView的adapter使用一样。不同的是,我们网格布局的adapter是需要设置每个单元视图的宽高的,而TableViewAdapter只需设置单元视图高度即可。代码中方法如下:

设置单元视图宽高,区分reuseId 设置单元视图宽高,不区分reuseId
sizeForCellByReuseId(string reuseId, function(number section, number row))
sizeForCell(function(number section, number row))
在和reuseId相关的方法中,每个方法都可以有多个同名的"重载"方法,当我们在reuseId(func)方法中返回多少种reuseId,与reuseId相关的方法就各自要多少种"重载",例如代码中返回两种reuseId,那么用来创建子view的方法initCellByReuseId就有两个"重载"(其实不是重载,sdk的底层用委托的方式实现调用)。类似的fillCellDataByReuseId等方法也是如此。 当然当我们reuseId只有一个时,完全可以使用不区分reuseId的方法去初始化adapter。简化如下:
    --设置对应子view的宽高
    adapter:sizeForCell(function()
        return Size(100, 100)
    end)
    --创建子view
    adapter:initCell(function(cell)

    end)
    --将子view与数据进行绑定赋值
    adapter:fillCellData(function(cell, section, row)
        cell.nameLabel:text("盖世英雄")
    end)
    --cell点击事件
    adapter:selectedRow(function(cell, section, row)
        print("点击了cell", row)
    end)

【注】 区分reuseId的方法不能与不区分reuseId的方法同时使用,如使用initCellByReuseId方法初始化单元视图时就不可再使用initCell方法。

以上代码完成了adapter初始化,之后调用collectionView:adapter(adapter)方法实现适配器绑定即可完成网格布局的一个简单实现。

总结

CollectionView、CollectionViewLayout和CollectionViewAdapter三者的关系如下代码所示:

collectionView:layout(collectionViewLayout)
collectionView:adapter(adapter)

Clone this wiki locally