ugui-(lua版无限循环列表)_skybeauty_新浪博客

第一:该类是控制无限循环的类

--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


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值