local UIList = {} UIList.__index = UIList --> Services local ReplicatedStorage = game:GetService("ReplicatedStorage") --> Dependencies local Utils = require(ReplicatedStorage.Tools.Utils) -- 子脚本自动注入 local function AutoInjectVariables(self) for varName, _ in pairs(self.Variables) do if typeof(varName) == "string" then local firstChar = string.sub(varName, 1, 1) local sixChar = string.sub(varName, 1, 6) local target if firstChar == "_" then if sixChar == "__list" then local prefab = Utils:FindInDescendantsUI(self.UIRoot, varName) target = UIList:Init(prefab) else -- _开头,递归查找 target = Utils:FindInDescendantsUI(self.UIRoot, varName) end if not target then error("自动注入失败:未找到UI节点 " .. varName) end self.Variables[varName] = target end end end end function UIList:Init(Prefab: Instance) local self = {} setmetatable(self, UIList) self.Data = {} self.Instances = {} self.Connections = {} self.LayoutOrderKey = nil self.Component = nil self.UIRoot = Prefab self.Org = Utils:FindInDescendantsUI(Prefab, "__org") self.Org.Visible = false return self end function UIList:AddComponent(Component: table) self.Component = Component end function UIList:SetData(Data: table) self.Data = Data self:Refresh() end -- 列表添加单个数据 function UIList:AddData(key: string, data: table) self.Data[key] = data self:SetSingleInstance(key, data) end -- 列表清除单个数据 function UIList:RemoveData(key) if self.Data[key] then for k, v in pairs(self.Instances) do if v.Data == self.Data[key] then for _, connection in pairs(v.Connections) do connection:Disconnect() end v.Connections = nil if v.UIRoot then v.UIRoot:Destroy() end if v.Destroy then v:Destroy() end if type(key) == "number" then table.remove(self.Instances, k) else self.Instances[k] = nil end break end end self.Data[key] = nil else warn("UIList:RemoveData() 数据不存在", key, self.Data) end end function UIList:SetLayoutOrder(keyName: string) self.LayoutOrderKey = keyName for _, ui in pairs(self.Instances) do ui.UIRoot.LayoutOrder = tonumber(ui.Data[keyName]) end end function UIList:SetSingleInstance(index: number, data: table) local child = self.Component:Init(data) child.TopUI = self.TopUI child.ListUI = self local uiInstance = self.Org:Clone() child.UIRoot = uiInstance uiInstance.Name = index uiInstance.Parent = self.Org.Parent if self.LayoutOrderKey then uiInstance.LayoutOrder = tonumber(child.Data[self.LayoutOrderKey]) end self.Instances[index] = child AutoInjectVariables(child) if child.OnInitFinish then child:OnInitFinish() end child:Refresh() uiInstance.Visible = true end function UIList:GetMinLayoutOrderInstance() local minOrder = math.huge local minInstance = nil for _, ui in pairs(self.Instances) do if ui.UIRoot.LayoutOrder < minOrder then minOrder = ui.UIRoot.LayoutOrder minInstance = ui end end return minInstance end function UIList:Refresh() for _, ui in pairs(self.Instances) do ui:Destroy() end self.Instances = {} if not self.Component then warn("UIList:Refresh() Component未设置") return end if self.Data then for k, v in pairs(self.Data) do self:SetSingleInstance(k, v) end end end function UIList:Clean() if self.TopUI then self.TopUI = nil end if self.ListUI then self.ListUI = nil end -- 清除自己的内容 for _, connection in pairs(self.Connections) do connection:Disconnect() end self.Connections = {} -- 清除下面组件的内容 for _, ui in pairs(self.Instances) do if ui.SignalConnections then for _, connection in pairs(ui.SignalConnections) do connection:DisconnectAll() end self.SignalConnections = nil end if ui.Connections then for _, connection in pairs(ui.Connections) do connection:Disconnect() end self.Connections = nil end if ui.UIRoot then ui.UIRoot:Destroy() end ui:Destroy() end self.Instances = {} end function UIList:Destroy() self:Clean() self.SignalConnections = nil self.Connections = nil self.Org:Destroy() if self.UIRoot then self.UIRoot:Destroy() end self = nil end return UIList