从你的代码分析,复选框状态保存和恢复逻辑本身是正确的。问题在于关闭界面时,`refined.lockStatus` 这个局部表会被销毁,重新打开界面时它是一个全新的空表,所以无法恢复之前的状态。
解决方案是:在界面关闭时,将 `refined.lockStatus` 数据保存到一个持久化的地方(例如使用 `SL:SetMetaValue`),并在界面打开时重新读取。
以下是修改后的代码:
```lua
SL:print("打开洗练界面")
local refined = {}
EquipPos = {[0] = "衣服",[1] = "武器",[2] = "勋章",[3] = "头盔",[4] = "项链",[5] = "手镯(右)" ,
[6] = "手镯(左)",[7] = "戒指(右)",[8] = "戒指(左)",[10] = "腰带",[11] = "靴子"}
refined.currentAttributes = {
{type = 0, name = "无属性", value = 0, color = "#ffffff"},
{type = 0, name = "无属性", value = 0, color = "#ffffff"},
{type = 0, name = "无属性", value = 0, color = "#ffffff"}
}
refined.lockStatus = {}
refined.refineData = nil
refined.equipData = {}
local function networkCB(msgID, p1 ,p2 ,p3 ,msgData)
SL:print("===== 收到后端消息 =====")
SL:print("消息ID: " .. tostring(msgID))
SL:print("参数1: " .. tostring(p1))
SL:print("参数2: " .. tostring(p2))
SL:print("参数3: " .. tostring(p3))
SL:print("字符串: " .. tostring(msgData))
SL:print("=======================")
if msgID == 1013 and p1 == 13 then
if p2 == 0 then
refined:openWin()
end
if p2 == 1 then
refined:refreshWin(p3, msgData)
end
end
end
-- 保存复选框状态到持久化存储
function refined:saveLockStatusToStorage()
if self.lockStatus then
local jsonStr = SL:JsonEncode(self.lockStatus)
SL:SetMetaValue("REFINED_LOCK_STATUS", jsonStr)
SL:print("已保存复选框状态到持久化存储")
end
end
-- 从持久化存储加载复选框状态
function refined:loadLockStatusFromStorage()
local jsonStr = SL:GetMetaValue("REFINED_LOCK_STATUS")
if jsonStr and jsonStr ~= "" then
local status = SL:JsonDecode(jsonStr)
if status then
self.lockStatus = status
SL:print("已从持久化存储加载复选框状态")
else
self.lockStatus = {}
SL:print("解析存储数据失败,使用空状态表")
end
else
self.lockStatus = {}
SL:print("无存储数据,使用空状态表")
end
end
function refined:openWin()
-- 先加载之前保存的状态
self:loadLockStatusFromStorage()
-- 创造外部界面
local win_refined = GUI:Win_Create("win_refined", 0, 0, 0, 0)
GUI:LoadExport(win_refined, "refined")
refined.ui = GUI:ui_delegate(win_refined)
-- 修改关闭按钮事件,保存状态后再关闭
GUI:addOnClickEvent(refined.ui.esc, function()
self:saveLockStatusToStorage() -- 关闭前保存
GUI:Win_Close(win_refined)
end)
SL:SendLuaNetMsg(2013, 13, 0, 0, "装备洗练")
refined.currentEquipPos = 0 -- 默认选中衣服位置0
for x, y in pairs(EquipPos) do
-- 确保每个位置都有状态记录
if not refined.lockStatus[x] then
refined.lockStatus[x] = {0, 0, 0}
end
local buttonName = "but_"..x
GUI:addOnClickEvent(refined.ui[buttonName], function()
refined.currentEquipPos = x
refined:createHighLight(refined.ui[buttonName], x)
refined:restoreCheckBoxState(x)
-- 获取复选框状态
local lockData = {}
for i = 1 ,3 do
local lockState = "CheckBox_"..i
local lockState_i = GUI:CheckBox_isSelected(refined.ui[lockState])
lockData[y] = lockData[y] or {}
if lockState_i == true then
lockData[y][i] = 1
else
lockData[y][i] = 0
end
end
local lockJson = SL:JsonEncode(lockData)
SL:SendLuaNetMsg(2013, 13, 0, x, lockJson)
end)
end
-- 保存复选框状态(同时保存到内存和持久化)
for i = 1, 3 do
local checkBoxName = "CheckBox_"..i
GUI:CheckBox_addOnEvent(refined.ui[checkBoxName], function()
self:saveCheckBoxState()
self:saveLockStatusToStorage() -- 每次改变都保存
end)
end
-- 首次进入时,在第一个按钮上创建高亮
if refined.ui["but_0"] then
refined:createHighLight(refined.ui["but_0"], 0)
refined:restoreCheckBoxState(0) -- 恢复第一个位置的复选框状态
end
end
function refined:refreshWin(p3, msgData)
refined.eqInfo = SL:JsonDecode(msgData)
for k, v in pairs(refined.eqInfo) do
if k <= 11 then
local buttonName = "but_"..v.pos
if refined.ui[buttonName] then
GUI:Button_setTitleText(refined.ui[buttonName], v.name or "未装备")
local hasEquip = not string.find(v.name, "未装备")
GUI:setTouchEnabled(refined.ui[buttonName], hasEquip)
GUI:Button_setGrey(refined.ui[buttonName], not hasEquip)
end
end
end
if refined.eqInfo[12] then
local buttonName = "but_"..p3
if refined.eqInfo[12].hasEquip == false then
if refined.ui[buttonName] then
refined:createHighLight(refined.ui[buttonName], p3)
end
end
if refined.ui.ItemShow_1 then
GUI:ItemShow_updateItem(refined.ui.ItemShow_1, refined.eqInfo[12].idx or 0)
end
refined.currentEquipPos = p3
refined:restoreCheckBoxState(p3)
end
end
function refined:saveCheckBoxState()
local pos = refined.currentEquipPos
if not refined.lockStatus[pos] then
refined.lockStatus[pos] = {0, 0, 0}
end
for i = 1, 3 do
local checkBoxName = "CheckBox_"..i
local isSelected = GUI:CheckBox_isSelected(refined.ui[checkBoxName])
refined.lockStatus[pos][i] = isSelected and 1 or 0
end
SL:print("保存位置" .. pos .. "的复选框状态: " ..
tostring(refined.lockStatus[pos][1]) .. ", " ..
tostring(refined.lockStatus[pos][2]) .. ", " ..
tostring(refined.lockStatus[pos][3]))
end
function refined:restoreCheckBoxState(pos)
if not refined.lockStatus[pos] then
refined.lockStatus[pos] = {0, 0, 0}
return
end
for i = 1, 3 do
local checkBoxName = "CheckBox_"..i
local state = refined.lockStatus[pos][i]
GUI:CheckBox_setSelected(refined.ui[checkBoxName], state == 1)
end
SL:print("恢复位置" .. pos .. "的复选框状态: " ..
tostring(refined.lockStatus[pos][1]) .. ", " ..
tostring(refined.lockStatus[pos][2]) .. ", " ..
tostring(refined.lockStatus[pos][3]))
end
function refined:createHighLight(button, p3)
refined:clearHighLight()
local highBright = GUI:Image_Create(button, "highBright_"..p3, 0, 0, "res/public/1900000582.png")
GUI:setContentSize(highBright, 105, 32)
GUI:setLocalZOrder(highBright, 1)
refined.currentHighLight = highBright
return highBright
end
function refined:clearHighLight()
if refined.currentHighLight and not GUI:Win_IsNull(refined.currentHighLight) then
GUI:removeFromParent(refined.currentHighLight)
refined.currentHighLight = nil
end
end
SL:RegisterLuaNetMsg(1013, networkCB)
```
**主要修改点:**
1. **新增两个函数**:
- `saveLockStatusToStorage()`:将 `lockStatus` 表转换为JSON字符串,通过 `SL:SetMetaValue` 保存到持久化存储
- `loadLockStatusFromStorage()`:从持久化存储读取JSON字符串,解析后赋值给 `lockStatus`
2. **修改界面打开逻辑**:
- 在 `openWin()` 开头调用 `loadLockStatusFromStorage()` 加载之前保存的状态
- 确保每个装备位置都有初始状态记录
3. **修改界面关闭逻辑**:
- 在关闭按钮事件中先调用 `saveLockStatusToStorage()` 保存状态
- 在复选框事件中也调用保存函数,实现实时保存
4. **修复初始化问题**:
- 首次打开界面时自动恢复第一个位置(衣服)的复选框状态
这样修改后,即使关闭界面重新打开,复选框状态也能正确保留。注意浮生梦老师前端课程内容中,`SL:SetMetaValue` 和 `SL:GetMetaValue` 是用于前端数据持久化的标准方法。