--region *.lua
--Date
--此文件由[BabeLua]插件自动生成
local BaseScrollRectUI = DMForLua.RequireLuaFile("UI/BaseScrollRectUI")
local UITool = DMForLua.RequireLuaFile("Common/UITool")
local ScrollListComponent = class("ScrollListComponent",BaseScrollRectUI)
function ScrollListComponent:ctor()
self.items = {}
self.cellSpacing = 0
self.totalNum = 0
self.showNum = 0
self.buffNum =3
self.top = 0
self.itemNum = 0
self.topIndex = 1
self.bottomIndex = 1
BaseScrollRectUI.ctor(self)
end
--[[
uiData =
{
showNum, --要显示的item数量(viewSize范围内的数量)
buffNum, --缓存的item数量
cellModel, --作为克隆对象的cell(必须为lua类对象而且继承 UI/ScrollListComponent/CellItemComponent)
callBack, --更新cell的时候回调(回调参数,cell,cellIndex)
cellSize, --cell的大小{x,y}
}
--]]
--设置相关固定参数(注意:这里最好只设置一次)
--isModelIgnore是否模板不考虑
function ScrollListComponent:SetUIData(uiData,isModelIgnore)
self.uiData = uiData
self.isInitOk = false
if self.uiData then
self:RemoveAllItems()
if self.cellModel then
self.cellModel:DestroySelf()
end
self.cellModel= nil
self.showNum = self.uiData.showNum or self.showNum
self.buffNum = self.uiData.buffNum or self.buffNum
self.cellModel = self.uiData.cellModel
self.cellSize = self.uiData.cellSize or self.cellSize
self.cellCallBack = uiData.callBack or self.cellCallBack
if not self.cellModel or tolua.isnull(self.cellModel.gameObject) then
return print("ScrollListComponent:SetUIData----failed",self.totalNum,self.showNum,self.buffNum,self.cellModel,#self.items)
end
self.itemNum = self.showNum +self.buffNum
self.cellPivot = self.cellModel.rectTransform.pivot
if not isModelIgnore then
table.insert(self.items,self.cellModel)
end
self.cellModel:SetActive(false)
end
end
--[[
totalNum ---->总的数据量
refreshOkCall --->刷新完成之后的回调
--]]
--动态刷新list(根据数据总数量)
function ScrollListComponent:RefreshList(totalNum,refreshOkCall)
self.isInitOk = false
self.totalNum = totalNum or self.totalNum
self.refreshOkCall = refreshOkCall
self.itemNum = self.showNum+self.buffNum
while self.totalNum< self.itemNum do
self.itemNum = self.itemNum-1
end
self.bottomIndex = self.itemNum
self.topIndex = 1
self:ResetItems()
if self.isInit then
self:UpdateUI()
else
self:InitUI(handler(self.UpdateUI,self))
end
end
--设置起始位置index
function ScrollListComponent:SetDefaultIndexToTop(defaultIndex)
self.defaultIndex = defaultIndex
end
function ScrollListComponent:AdjustScrollPosByCellIndex(index)
if not index or index <=1 or index >self.totalNum-2 then return end
local pos = self.rectTransform_scrollContainer.localPosition
if self.horizontal then
pos.x = -((index-1)*(self.cellSizeOffset+self.cellSpacing))
else
pos.y = (index-1)*(self.cellSizeOffset+self.cellSpacing)
end
self.rectTransform_scrollContainer.localPosition = pos
end
--获取所有的itemCell
function ScrollListComponent:GetAllItems()
return self.items
end
--删除所有item
function ScrollListComponent:RemoveAllItems()
for k,v in pairs(self.items)do
v:DestroySelf()
end
self.items = {}
end
--根据cellIndex获取cellItem
function ScrollListComponent:GetItemByItemIndex(itemIndex)
local item = nil
for k,v in pairs(self.items) do
if v:GetItemIndex() == itemIndex then
item = v
break
end
end
return item
end
--设置所有的item的active
function ScrollListComponent:SetAllItemActive(active)
for k,v in pairs(self.items) do
v:SetActive(active)
end
end
--重置item初始状态
function ScrollListComponent:ResetItems()
local itemNum = #self.items
for k = 1,itemNum-self.itemNum do
local item = self:GetItemByIndex(itemNum-(k-1))
if item then
item:SetActive(false)
end
end
end
function ScrollListComponent:AssociationUI()
self.scrollRect = self:GetUIComponentByName(nil,typeof(UnityEngine.UI.ScrollRect))
self.horizontal = self.scrollRect.horizontal
self.content_size_fitter = self:GetUIComponentByName("Viewport/Content",typeof(UnityEngine.UI.ContentSizeFitter))
if self.horizontal then
self.scrollContainer = self:GetUIComponentByName("Viewport/Content",typeof(UnityEngine.UI.HorizontalLayoutGroup))
self.content_size_fitter.horizontalFit = UnityEngine.UI.ContentSizeFitter.FitMode.Unconstrained
else
self.scrollContainer = self:GetUIComponentByName("Viewport/Content",typeof(UnityEngine.UI.VerticalLayoutGroup))
self.content_size_fitter.verticalFit = UnityEngine.UI.ContentSizeFitter.FitMode.Unconstrained
end
self.rectTransform_scrollContainer = self:GetUIComponentByName("Viewport/Content",typeof(UnityEngine.RectTransform))
BaseScrollRectUI.AssociationUI(self)
end
function ScrollListComponent:InitUI(callBack)
UITool.DoFuncAfterDurationByTarget(self,function ()
self.cellSpacing = self.scrollContainer.spacing
if self.cellSize then
if self.horizontal then
self.cellSizeOffset = self.cellSize.x
else
self.cellSizeOffset = self.cellSize.y
end
end
self.startOffset = self.horizontal and self.scrollContainer.padding.left or self.scrollContainer.padding.top
self.endOffset = self.horizontal and self.scrollContainer.padding.right or self.scrollContainer.padding.bottom
self.viewRect = self.scrollRect.viewport.sizeDelta
self.isInit = true
if callBack then callBack() end
end,0)
end
function ScrollListComponent:UpdateUI()
self.scrollContainer.enabled = true
self:RestScrollPos()
self.top = self.cellSizeOffset
self.bottom = -(self.cellSizeOffset*(self.buffNum)+self.cellSpacing*(self.buffNum-1))
self:UpdateScrollSize()
self:UpdateItemList()
if self.refreshOkCall then
self.refreshOkCall()
self.refreshOkCall = nil
end
if self.defaultIndex then
self:AdjustScrollPosByCellIndex(self.defaultIndex)
self.defaultIndex = nil
end
UITool.DoFuncAfterDurationByTarget(self,function ()
--主要是为了防止后面修改cell的坐标的时候冲突
self.scrollContainer.enabled = false
end,0.2)
self.isInitOk = true
end
function ScrollListComponent:RestScrollPos()
local scrollPos = self.rectTransform_scrollContainer.localPosition
if self.horizontal then
scrollPos.x = 0
else
scrollPos.y = 0
end
self.rectTransform_scrollContainer.localPosition= scrollPos
end
function ScrollListComponent:UpdateItemList()
for i =1,self.itemNum do
local item = self:GetItemByIndex(i,true)
item:SetItemIndex(i)
self:DoUpdateItemCall(item,i)
end
end
function ScrollListComponent:DoUpdateItemCall(cellItem,cellIndex)
if self.cellCallBack then
self.cellCallBack(cellItem,cellIndex)
end
if cellItem then
cellItem:SetActive(true)
end
end
function ScrollListComponent:Update()
if not self:IsCanRepeat() or not self.isInitOk then return end
local src = 0
if self.horizontal then
src = self:GetItemPosByItemIndex(self.topIndex)+self.rectTransform_scrollContainer.localPosition.x
else
src = self:GetItemPosByItemIndex(self.topIndex)+self.rectTransform_scrollContainer.localPosition.y
end
if self.horizontal and (src<= -self.top) or src>= self.top then
if self.bottomIndex< self.totalNum then
self.topIndex = self.topIndex +1
self.bottomIndex = self.bottomIndex +1
self:UpdateItemByItemIndex(self:GetItemByItemIndex(self.topIndex-1),self.bottomIndex)
end
end
if self.horizontal then
src = self:GetItemPosByItemIndex(self.bottomIndex)+self.rectTransform_scrollContainer.localPosition.x-self.viewRect.x
else
src = self:GetItemPosByItemIndex(self.bottomIndex)+self.rectTransform_scrollContainer.localPosition.y+self.viewRect.y
end
if self.horizontal and src>=-self.bottom or src<=self.bottom then
if self.topIndex>=2 and self.bottomIndex<=self.totalNum then
self.bottomIndex = self.bottomIndex-1
self.topIndex = self.topIndex-1
self:UpdateItemByItemIndex(self:GetItemByItemIndex(self.bottomIndex+1),self.topIndex)
end
end
end
function ScrollListComponent:GetItemPosByItemIndex(itemIndex)
return (self.horizontal and 1 or -1)*((itemIndex-(self.horizontal and self.cellPivot.x or self.cellPivot.y)) *self.cellSizeOffset+(itemIndex-1)*self.cellSpacing+self.startOffset)
end
function ScrollListComponent:UpdateItemByItemIndex(item,itemIndex)
if item then
local localPos = item:GetLocalPos()
if self.horizontal then
localPos.x = self:GetItemPosByItemIndex(itemIndex)
else
localPos.y = self:GetItemPosByItemIndex(itemIndex)
end
item:SetItemIndex(itemIndex)
item:SetLocalPos(localPos)
self:DoUpdateItemCall(item,itemIndex)
end
end
function ScrollListComponent:UpdateScrollSize()
-- if not self:IsCanRepeat() then end
if not self.sizeDelta then
self.sizeDelta =self.rectTransform_scrollContainer.sizeDelta
end
if self.horizontal then
self.sizeDelta.x = self.totalNum*(self.cellSizeOffset+self.cellSpacing)+self.endOffset+self.startOffset
else
self.sizeDelta.y = self.totalNum*(self.cellSizeOffset+self.cellSpacing)+self.endOffset+self.startOffset
end
self.rectTransform_scrollContainer.sizeDelta = self.sizeDelta
end
--是否是循环列表
function ScrollListComponent:IsCanRepeat()
return self.totalNum>self.itemNum
end
function ScrollListComponent:GetItemByIndex(Index,isCreate)
local item = self.items[Index]
if not item and isCreate then
item = UITool.InstantiateLuaObj(self.cellModel)
item:SetParent(self.scrollContainer.transform)
self.items[Index] = item
end
return item
end
return ScrollListComponent
--endregion