第一:该类是控制无限循环的类
--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
第二:该类是控制每个cell的基类
--region *.lua
--Date
--此文件由[BabeLua]插件自动生成
local UIBase = DMForLua.RequireLuaFile("UI/UIBase")
local Messenger = DMForLua.RequireLuaFile("Common/Messenger")
local CellItemComponent = class("CellItemComponent",UIBase)
function CellItemComponent:GetLocalPos()
return self.rectTransform.localPosition
end
function CellItemComponent:SetLocalPos(localPos)
self.rectTransform.localPosition = localPos or self:GetLocalPos()
end
function CellItemComponent:SetItemIndex(itemIndex)
self.itemIndex = itemIndex
end
function CellItemComponent:GetItemIndex()
return self.itemIndex
end
return CellItemComponent
--endregion
第三:该类是控制每个UI的基类
--region *.lua
--Date
--此文件由[BabeLua]插件自动生成
local UITool = DMForLua.RequireLuaFile("Common/UITool")
local Messenger = DMForLua.RequireLuaFile("Common/Messenger")
local UIDepth = DMForLua.RequireLuaFile("UI/UIDepth")
local UIBase = class("UIBase")
local TYPE_GAMEOBJECT = typeof(UnityEngine.GameObject)
local TYPE_TRANSFORM = typeof(UnityEngine.Transform)
function UIBase:ctor()
self.__isInit = false
self.__widgets = {} --二维数组(一级key为名称,二级key为类型)返回对象
end
--region *.lua[[ 关联方法 ]]
function UIBase:Association(luaComponent)
self.__widgets = {}
self.luaComponent = luaComponent
self.gameObject = self.luaComponent.gameObject
self.transform = self.luaComponent.transform
self.animator = self.luaComponent.animator
self.rectTransform = self:GetUIComponentByName(nil,typeof(UnityEngine.RectTransform))
self.luaFilePath = self.luaComponent.luaFilePath
end
--endregion
function UIBase:IsActive()
return self.gameObject.activeSelf
end
function UIBase:SetActive(isActive)
self.gameObject:SetActive(isActive)
end
--[[ 关联UI 整个生命周期只会执行一次 ]]
function UIBase:AssociationUI()
end
--[[关联luaTable]]
function UIBase:AssociationLuaTable()
self.__isInit = true
end
--endregion
--播放动画
function UIBase:PlayActionByName(actionName)
if tolua.isnull(self.animator) then
return
end
self.animator:CrossFade(actionName,0,0,0)
end
--设置该节点在父节点的相对位置
function UIBase:SetAsFirstSibling()
if tolua.isnull(self.transform) then return end
self.transform:SetAsFirstSibling()
end
--设置ui的唯一id
function UIBase:SetUIId(id)
self.uiId = id
end
--获取UI的ID
function UIBase:GetUIId()
return self.uiId
end
--设置父节点
function UIBase:SetParent(parent,isTrue)
if not isTrue then
isTrue = false
end
if not parent then
UnityEngine.Debug.Log("UIBase:SetParent---failed")
UnityEngine.Debug.Log(parent)
return
end
self.transform:SetParent(parent,isTrue)
end
--region *.lua [[销毁对象]]
function UIBase:DestroySelf()
UnityEngine.GameObject.DestroyImmediate(self.gameObject)
end
--endregion
--region *.lua [[获取当前luapath]]
function UIBase:GetLuaPath()
return self.luaFilePath
end
--endregion
function UIBase:Awake()
self:AssociationUI()
end
function UIBase:Start()
end
--region *.lua [[设置渲染层级]]
function UIBase:SetDepath(layerIndex)
-- if self.layerIndex == layerIndex then return end
self.layerIndex = layerIndex
-- 调整Canvas的SortingOrder, UI与粒子特效的深度排列 --
local uiDepathWidget = self.gameObject:GetComponent(typeof(UIDepthWidget))
if not uiDepathWidget then
uiDepathWidget= self.gameObject:AddComponent(typeof(UIDepthWidget))
uiDepathWidget.order = uiDepathWidget.orignalOrder
end
uiDepathWidget.order = uiDepathWidget.orignalOrder
local targetOrder = layerIndex * PopupStackUIDepth.PanelDepthUnit
local tempUIDepthWidgets = self.transform:GetComponentsInChildren(typeof(UIDepthWidget),true)
for k = 0,tempUIDepthWidgets.Length -1 do
local depathWidget = tempUIDepthWidgets[k]
depathWidget.order = targetOrder + depathWidget.orignalOrder
UIDepth.SetDepth(depathWidget.gameObject, depathWidget.order, depathWidget.depthType)
end
end
--endregion
--region *.lua [[获取组件]]
function UIBase:GetUIComponentByName(widgetName,widgetType)
widgetName = widgetName or ""
widgetType = widgetType or TYPE_GAMEOBJECT
local target = nil
local widget = nil
if widgetName=="" then
widget = self.__widgets[self.transform]
if widget then
if widgetType ~=nil and widgetType ~= TYPE_GAMEOBJECT then
target =widget[widgetType]
if not target then
widget = self.transform
target = widget.gameObject:GetComponent(widgetType)
self.__widgets[self.transform][widgetType] = target
end
else
target = self.gameObject
end
else
self.__widgets[self.transform] = {}
self.__widgets[self.transform][TYPE_TRANSFORM] = self.transform
self.__widgets[self.transform][TYPE_GAMEOBJECT] = self.gameObject
widget = self.transform
if widgetType ~=nil and widgetType ~= TYPE_GAMEOBJECT then
target = widget.gameObject:GetComponent(widgetType)
self.__widgets[self.transform][widgetType] = target
else
target = widget.gameObject
end
end
else
widget = self.__widgets[widgetName]
if widget then
target = widget[widgetType]
if not target then
widget = widget[TYPE_GAMEOBJECT]
if tolua.isnull(widget) then
widget = self.transform:Find(widgetName)
if not tolua.isnull(widget) then
self.__widgets[widgetName][TYPE_TRANSFORM] = widget
self.__widgets[widgetName][TYPE_GAMEOBJECT] = widget.gameObject
if widgetType ~= TYPE_GAMEOBJECT then
target = widget.gameObject:GetComponent(widgetType)
self.__widgets[widgetName][widgetType] = target
else
target = widget.gameObject
end
end
else
if widgetType ~= TYPE_GAMEOBJECT then
target = widget.gameObject:GetComponent(widgetType)
self.__widgets[widgetName][widgetType] = target
else
target = widget.gameObject
end
end
end
else
self.__widgets[widgetName] = {}
widget = self.transform:Find(widgetName)
if not tolua.isnull(widget) then
self.__widgets[widgetName][TYPE_TRANSFORM] = widget
self.__widgets[widgetName][TYPE_GAMEOBJECT] = widget.gameObject
if widgetType ~=nil and widgetType ~= TYPE_GAMEOBJECT then
target = widget.gameObject:GetComponent(widgetType)
self.__widgets[widgetName][widgetType] = target
else
target = widget.gameObject
end
end
end
end
if target == nil then
UnityEngine.Debug.Log(string.format("widget not find::::className =%s,widgetName=%s",self.__cname or "nil",widgetName or "nil"))
UnityEngine.Debug.Log(widgetType or "nil")
end
return target
end
--endregion
--region *.lua [[获取该节点下的同类型组件]]
function UIBase:GetComponentsInChildren(childType,gameObj,isRecursive)
gameObj = gameObj or self.gameObject
local childArray = {}
if isRecursive then
local childs = gameObj:GetComponentsInChildren(childType)
for i = 0,childs.Length-1 do
table.insert(childArray,childs[i])
end
else
local transform = gameObj.transform
for i = 0,transform.childCount-1 do
local child = transform:GetChild(i)
local childObj = child.gameObject:GetComponent(childType)
if childObj then
table.insert(childArray,childObj)
end
end
end
return childArray
end
--endregion
--region *.lua [[销毁]]
function UIBase:OnDestroy()
UITool.RemoveEventListenerByTarget(self)
UITool.RemoveRunningActionByTarget(self)
UITool.RemoveResUpdateByTarget(self)
UITool.RemoveAllButtonListenerByTarget(self)
DLNetMsgDispatcher:Instance():RemoveRequestListenerByTarget(self)
self = nil
end
--endregion
return UIBase
--endregion