2025-07-18 01:11:49 +08:00
|
|
|
|
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 = {}
|
2025-07-19 03:03:02 +08:00
|
|
|
|
self.LayoutOrderKey = nil
|
2025-07-18 01:11:49 +08:00
|
|
|
|
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
|
|
|
|
|
|
2025-07-23 01:04:27 +08:00
|
|
|
|
-- 列表添加单个数据
|
|
|
|
|
function UIList:AddData(key: string, data: table)
|
|
|
|
|
self.Data[key] = data
|
|
|
|
|
self:SetSingleInstance(key, data)
|
2025-07-18 01:11:49 +08:00
|
|
|
|
end
|
|
|
|
|
|
2025-07-23 01:04:27 +08:00
|
|
|
|
-- 列表清除单个数据
|
|
|
|
|
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
|
2025-07-22 01:56:56 +08:00
|
|
|
|
end
|
2025-07-23 01:04:27 +08:00
|
|
|
|
self.Data[key] = nil
|
|
|
|
|
else
|
|
|
|
|
warn("UIList:RemoveData() 数据不存在", key, self.Data)
|
2025-07-22 01:56:56 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2025-07-19 03:03:02 +08:00
|
|
|
|
function UIList:SetLayoutOrder(keyName: string)
|
|
|
|
|
self.LayoutOrderKey = keyName
|
|
|
|
|
for _, ui in pairs(self.Instances) do
|
|
|
|
|
ui.UIRoot.LayoutOrder = tonumber(ui.Data[keyName])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2025-07-18 01:11:49 +08:00
|
|
|
|
function UIList:SetSingleInstance(index: number, data: table)
|
|
|
|
|
local child = self.Component:Init(data)
|
2025-07-19 03:03:02 +08:00
|
|
|
|
child.TopUI = self.TopUI
|
|
|
|
|
child.ListUI = self
|
2025-07-18 01:11:49 +08:00
|
|
|
|
|
|
|
|
|
local uiInstance = self.Org:Clone()
|
|
|
|
|
child.UIRoot = uiInstance
|
|
|
|
|
uiInstance.Name = index
|
|
|
|
|
uiInstance.Parent = self.Org.Parent
|
2025-07-19 03:03:02 +08:00
|
|
|
|
if self.LayoutOrderKey then
|
|
|
|
|
uiInstance.LayoutOrder = tonumber(child.Data[self.LayoutOrderKey])
|
|
|
|
|
end
|
2025-07-18 01:11:49 +08:00
|
|
|
|
self.Instances[index] = child
|
|
|
|
|
|
|
|
|
|
AutoInjectVariables(child)
|
2025-07-19 03:03:02 +08:00
|
|
|
|
if child.OnInitFinish then child:OnInitFinish() end
|
2025-07-18 01:11:49 +08:00
|
|
|
|
child:Refresh()
|
|
|
|
|
uiInstance.Visible = true
|
|
|
|
|
end
|
|
|
|
|
|
2025-07-19 03:03:02 +08:00
|
|
|
|
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
|
|
|
|
|
|
2025-07-18 01:11:49 +08:00
|
|
|
|
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()
|
2025-07-19 03:03:02 +08:00
|
|
|
|
if self.TopUI then self.TopUI = nil end
|
|
|
|
|
if self.ListUI then self.ListUI = nil end
|
2025-07-18 01:11:49 +08:00
|
|
|
|
-- 清除自己的内容
|
|
|
|
|
for _, connection in pairs(self.Connections) do
|
|
|
|
|
connection:Disconnect()
|
|
|
|
|
end
|
|
|
|
|
self.Connections = {}
|
|
|
|
|
|
|
|
|
|
-- 清除下面组件的内容
|
|
|
|
|
for _, ui in pairs(self.Instances) do
|
2025-07-22 01:56:56 +08:00
|
|
|
|
if ui.SignalConnections then
|
|
|
|
|
for _, connection in pairs(ui.SignalConnections) do
|
|
|
|
|
connection:DisconnectAll()
|
|
|
|
|
end
|
|
|
|
|
self.SignalConnections = nil
|
2025-07-18 01:11:49 +08:00
|
|
|
|
end
|
|
|
|
|
|
2025-07-22 01:56:56 +08:00
|
|
|
|
if ui.Connections then
|
|
|
|
|
for _, connection in pairs(ui.Connections) do
|
|
|
|
|
connection:Disconnect()
|
|
|
|
|
end
|
|
|
|
|
self.Connections = nil
|
2025-07-18 01:11:49 +08:00
|
|
|
|
end
|
|
|
|
|
|
2025-07-19 03:03:02 +08:00
|
|
|
|
if ui.UIRoot then ui.UIRoot:Destroy() end
|
2025-07-18 01:11:49 +08:00
|
|
|
|
ui:Destroy()
|
|
|
|
|
end
|
|
|
|
|
self.Instances = {}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function UIList:Destroy()
|
|
|
|
|
self:Clean()
|
|
|
|
|
self.SignalConnections = nil
|
|
|
|
|
self.Connections = nil
|
|
|
|
|
self.Org:Destroy()
|
2025-07-23 01:04:27 +08:00
|
|
|
|
if self.UIRoot then self.UIRoot:Destroy() end
|
2025-07-18 01:11:49 +08:00
|
|
|
|
self = nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return UIList
|