2025-07-23 01:04:27 +08:00

184 lines
4.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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