379 lines
13 KiB
C#
379 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using FairyGUI;
|
|
using FGUI.LG_secretAlbums;
|
|
using FGUI.ZM_Common_01;
|
|
using SGModule.Common.Helper;
|
|
using SGModule.NetKit;
|
|
using UnityEngine;
|
|
|
|
namespace BallKingdomCrush
|
|
{
|
|
public class SecretAlbumsUI : BaseUI
|
|
{
|
|
private const int MaxVisibleCount = 6; // 一屏显示6个
|
|
private const int PreloadCount = 2; // 上下各预加载一屏
|
|
|
|
private readonly Dictionary<int, bool> _fileIsExist = new();
|
|
private readonly Dictionary<int, GLoader> activeLoaders = new();
|
|
private SecretAlbumsUICtrl ctrl;
|
|
private SecretAlbumsModel model;
|
|
private com_scAlbums ui;
|
|
|
|
public SecretAlbumsUI(SecretAlbumsUICtrl ctrl) : base(ctrl)
|
|
{
|
|
uiName = UIConst.SecretAlbumsUI;
|
|
this.ctrl = ctrl;
|
|
}
|
|
|
|
protected override void SetUIInfo(UIInfo uiInfo)
|
|
{
|
|
uiInfo.packageName = "LG_secretAlbums";
|
|
uiInfo.assetName = "com_scAlbums";
|
|
uiInfo.layerType = UILayerType.Popup;
|
|
uiInfo.isNeedOpenAnim = false;
|
|
uiInfo.isNeedCloseAnim = false;
|
|
uiInfo.isNeedUIMask = true;
|
|
}
|
|
|
|
#region 生命周期
|
|
protected override void OnInit()
|
|
{
|
|
//model = ModuleManager.Instance.GetModel(ModelConst.SecretAlbumsModel) as SecretAlbumsModel;
|
|
// 初始化GLoader池,设置最大缓存数
|
|
GLoaderPool.Instance.Init(null, 10, 464, 642);
|
|
}
|
|
|
|
protected override void OnClose()
|
|
{
|
|
// 1. 解除 UI 对 Loader 的引用
|
|
for (var i = 0; i < ui.sc_list.numChildren; i++)
|
|
{
|
|
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
|
if (item != null && item.com_pic.picture != null) item.com_pic.picture = null; // 清掉 GLoader 引用
|
|
}
|
|
|
|
activeLoaders.Clear();
|
|
_fileIsExist.Clear();
|
|
|
|
GLoaderPool.Instance.DisposeAll();
|
|
|
|
TextureHelper.ClearMaterialPool();
|
|
|
|
// 强制卸载未使用的资源
|
|
// Resources.UnloadUnusedAssets();
|
|
// MemoryManager.CleanMemoryMonitor();
|
|
}
|
|
|
|
protected override void OnBind()
|
|
{
|
|
ui = baseUI as FGUI.LG_secretAlbums.com_scAlbums;
|
|
}
|
|
|
|
private List<SecretAlbums> _secretData = new List<SecretAlbums>();
|
|
private List<SecretAlbums> _secretData1 = new List<SecretAlbums>();
|
|
protected override void OnOpenBefore(object args)
|
|
{
|
|
if (Screen.safeArea.y != 0)
|
|
{
|
|
ui.btn_gold.y += 68;
|
|
ui.btn_close.y += 68;
|
|
ui.sc_list.y += 68;
|
|
}
|
|
|
|
var eventName = GameHelper.IsAdModelOfPay() ? ADEventTrack.AD_Event : ADEventTrack.MaxPayEvent;
|
|
TrackKit.SendEvent(eventName, ADEventTrack.Property.secret_albums_show);
|
|
|
|
_secretData = ConfigSystem.GetSecretAlbumsConfig();
|
|
InitView();
|
|
}
|
|
|
|
protected override void OnOpen(object args)
|
|
{
|
|
}
|
|
|
|
protected override void OnHide()
|
|
{
|
|
}
|
|
|
|
protected override void OnDisplay(object args)
|
|
{
|
|
}
|
|
#endregion
|
|
|
|
#region 消息
|
|
protected override void AddListener()
|
|
{
|
|
GameDispatcher.Instance.AddListener(GameMsg.UnlockSecretSuccess, UnlockSuccess);
|
|
GameDispatcher.Instance.AddListener(GameMsg.Gold_refresh, set101);
|
|
}
|
|
protected override void RemoveListener()
|
|
{
|
|
GameDispatcher.Instance.RemoveListener(GameMsg.UnlockSecretSuccess, UnlockSuccess);
|
|
GameDispatcher.Instance.RemoveListener(GameMsg.Gold_refresh, set101);
|
|
}
|
|
#endregion
|
|
|
|
void UnlockSuccess(object str = null)
|
|
{
|
|
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
|
ui.sc_list.itemRenderer = ItemRender;
|
|
ui.sc_list.numItems = _secretData.Count;
|
|
}
|
|
|
|
private void set101(object obj)
|
|
{
|
|
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
|
}
|
|
|
|
//初始化页面逻辑
|
|
private void InitView()
|
|
{
|
|
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
|
ui.btn_close.SetClick(CtrlCloseUI);
|
|
|
|
UnlockSuccess();
|
|
|
|
InitScroll();
|
|
}
|
|
|
|
private void InitScroll()
|
|
{
|
|
ui.sc_list.scrollPane.onScroll.Add(OnScrollUpdate);
|
|
ui.sc_list.scrollPane.onScrollEnd.Add(OnScrollEnd); // 保留结束时的整理
|
|
|
|
OnScrollEnd();
|
|
}
|
|
|
|
// 滑动过程中实时更新
|
|
private void OnScrollUpdate()
|
|
{
|
|
UpdateVisibleAndPreload();
|
|
}
|
|
|
|
// 核心刷新逻辑
|
|
private void UpdateVisibleAndPreload()
|
|
{
|
|
if (_secretData == null || _secretData.Count == 0) return;
|
|
|
|
var firstVisibleIndex = ui.sc_list.GetFirstChildInView();
|
|
var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.sc_list.numItems - 1);
|
|
|
|
var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
|
|
var endIndex = Mathf.Min(ui.sc_list.numItems - 1, lastVisibleIndex + PreloadCount);
|
|
|
|
// 回收超出范围 loader
|
|
var keysToRemove = new List<int>();
|
|
foreach (var kv in activeLoaders)
|
|
{
|
|
var idx = kv.Key;
|
|
if (idx < startIndex || idx > endIndex)
|
|
{
|
|
GLoaderPool.Instance.ReturnLoader(kv.Value);
|
|
var oldItem = ui.sc_list.GetChildAt(idx) as item_scalnums;
|
|
if (oldItem != null) oldItem.com_pic.picture = null;
|
|
keysToRemove.Add(idx);
|
|
}
|
|
}
|
|
|
|
foreach (var k in keysToRemove) activeLoaders.Remove(k);
|
|
|
|
|
|
// 分配 loader 并加载图片
|
|
for (var i = startIndex; i <= endIndex; i++)
|
|
{
|
|
if (activeLoaders.ContainsKey(i)) continue;
|
|
|
|
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
|
if (item == null) continue;
|
|
|
|
if (item.com_pic.picture != null && !item.com_pic.picture.isDisposed)
|
|
GLoaderPool.Instance.ReturnLoader(item.com_pic.picture);
|
|
|
|
var loader = GLoaderPool.Instance.GetLoader();
|
|
item.com_pic.picture = loader;
|
|
item.com_pic.AddChild(loader);
|
|
loader.SetSize(item.com_pic.width, item.com_pic.height);
|
|
|
|
_fileIsExist.TryGetValue(i, out var value);
|
|
if (!value)
|
|
{
|
|
var localPath = Path.Combine(TextureHelper.getResPath(), _secretData[i].Name + ".jpg");
|
|
|
|
if (File.Exists(localPath))
|
|
{
|
|
_fileIsExist[i] = true;
|
|
Debug.Log($"[SetImgLoader] 本地存在,直接加载 {_secretData[i].Name}");
|
|
CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(_secretData[i].Name, loader, null,
|
|
"SecretAlbums/"));
|
|
}
|
|
else
|
|
{
|
|
_fileIsExist[i] = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(_secretData[i].Name, loader, null,
|
|
"SecretAlbums/"));
|
|
}
|
|
|
|
activeLoaders[i] = loader;
|
|
}
|
|
|
|
// Debug.Log($"[ScrollUpdate] active loaders={activeLoaders.Count}, pool={GLoaderPool.Instance.GetPoolCount()}, inUse={GLoaderPool.Instance.GetInUseCount()}");
|
|
}
|
|
|
|
private void OnScrollEnd()
|
|
{
|
|
if (_secretData == null || _secretData.Count == 0) return;
|
|
|
|
var firstVisibleIndex = ui.sc_list.GetFirstChildInView();
|
|
var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.sc_list.numItems - 1);
|
|
|
|
var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
|
|
var endIndex = Mathf.Min(ui.sc_list.numItems - 1, lastVisibleIndex + PreloadCount);
|
|
|
|
// Debug.Log($"[ScrollEnd] start index={startIndex} end index={endIndex}");
|
|
|
|
|
|
var tasks = new List<(GLoader loader, string fileName, Action<NTexture> callback, string folder, string localFolder)>();
|
|
// 分配 loader 并加载图片
|
|
for (var i = startIndex; i <= endIndex; i++)
|
|
{
|
|
_fileIsExist.TryGetValue(i, out var value);
|
|
|
|
if (value) continue;
|
|
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
|
if (item == null) continue;
|
|
if (item.com_pic.picture != null && !item.com_pic.picture.isDisposed)
|
|
GLoaderPool.Instance.ReturnLoader(item.com_pic.picture);
|
|
var loader = GLoaderPool.Instance.GetLoader();
|
|
item.com_pic.picture = loader;
|
|
item.com_pic.AddChild(loader);
|
|
loader.SetSize(item.com_pic.width, item.com_pic.height);
|
|
|
|
var idx = i;
|
|
tasks.Add((loader, _secretData[i].Name, texture =>
|
|
{
|
|
if (texture != null) _fileIsExist[idx] = true;
|
|
}, "SecretAlbums/", FolderNames.SecretName));
|
|
|
|
activeLoaders[i] = loader;
|
|
}
|
|
|
|
if (tasks.Count > 0)
|
|
{
|
|
TextureHelper.SetImgLoaders(tasks);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private void ItemRender(int index, GObject obj)
|
|
{
|
|
var item = (item_scalnums)obj;
|
|
|
|
item.text_id.text = _secretData[index].id.ToString();
|
|
|
|
var isUnlock = DataMgr.SecretUnlockList.Value.Contains(index);
|
|
|
|
item.btn_unlock.pay_type.selectedIndex = _secretData[index].PayType;
|
|
|
|
if (_secretData[index].PayType == 0)
|
|
item.btn_unlock.title = GameHelper.getPrice((decimal)_secretData[index].DiscountPrice);
|
|
else if (_secretData[index].PayType == 1)
|
|
item.btn_unlock.title = _secretData[index].GoldCoins.ToString();
|
|
else if (_secretData[index].PayType == 2) item.btn_unlock.title = _secretData[index].AD + "AD";
|
|
|
|
if (isUnlock)
|
|
{
|
|
item.btn_unlock.pay_type.selectedIndex = 3;
|
|
if (_secretData[index].SubscribeUnlock == 1)
|
|
{
|
|
item.vip.selectedIndex = 2;
|
|
item.btn_unlock.pay_type.selectedIndex = 4;
|
|
}
|
|
item.btn_unlock.title = "GO";
|
|
}
|
|
else
|
|
{
|
|
if (_secretData[index].SubscribeUnlock == 1)
|
|
{
|
|
item.vip.selectedIndex = 1;
|
|
item.btn_unlock.pay_type.selectedIndex = 4;
|
|
}
|
|
}
|
|
|
|
item.btn_null.SetClick(GotoNext);
|
|
|
|
item.un_lock.selectedIndex = isUnlock ? 1 : 0;
|
|
|
|
item.btn_unlock.SetClick(GotoNext);
|
|
|
|
item.peple_num.text = GetPepleNum(_secretData[index].Quantity).ToString();
|
|
|
|
item.hot.selectedIndex = _secretData[index].HotType;
|
|
void GotoNext()
|
|
{
|
|
var da = _secretData;
|
|
var data = new AlbumPreviewData
|
|
{
|
|
Index = index,
|
|
State = _secretData[index].State,
|
|
Price = _secretData[index].Price,
|
|
PayType = _secretData[index].PayType,
|
|
SubscribeUnlock = _secretData[index].SubscribeUnlock,
|
|
DiscountPrice = _secretData[index].DiscountPrice,
|
|
Name = _secretData[index].Name,
|
|
Name2 = _secretData[index].Name2,
|
|
GoldCoins = _secretData[index].GoldCoins,
|
|
AD = _secretData[index].AD,
|
|
CD = _secretData[index].CD
|
|
};
|
|
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.SecretAlbumsNextUI_Open, data);
|
|
}
|
|
}
|
|
|
|
|
|
private int GetPepleNum(float quantity)
|
|
{
|
|
// 获取当前时间
|
|
DateTime now = DateTime.Now;
|
|
|
|
// 计算当天已经过去的分钟数(从凌晨 0 点开始算)
|
|
int minutesPassedToday = now.Hour * 60 + now.Minute;
|
|
|
|
// 计算人数
|
|
int num = Mathf.FloorToInt(quantity * minutesPassedToday);
|
|
|
|
return num;
|
|
}
|
|
}
|
|
|
|
public class AlbumPreviewData
|
|
{
|
|
public int[] State;
|
|
public int Index;
|
|
public string Name;
|
|
public float Price;
|
|
public int SubscribeUnlock;
|
|
public int PayType;
|
|
public float DiscountPrice;
|
|
public string Name2;
|
|
public int GoldCoins;
|
|
public int AD;
|
|
public int CD;
|
|
}
|
|
|
|
public enum UnlockPayType
|
|
{
|
|
Pay = 0,
|
|
Coin = 1,
|
|
Ad = 2,
|
|
None = 3,
|
|
}
|
|
}
|