# StrayFog 框架 UI窗口开发指南 ## 一、UI窗口基础 ### 1.1 窗口创建流程 ```csharp [HFAssetBundlePath(enHFLanguageRootFolder.ASSETS_GAME_GAMEHFRESOURCE, "UIWindows/Bag/BagWindow.prefab")] [HFUIWindowLayer(enHFUICanvasLayer.UIWindow, enHFUIWindowLayer.Fixed, isIgnoreCloseByESC = false)] public class BagWindow : AbsHFUIWindow { // ========== UI组件 ========== private SFUI_Button BtnClose; private SFUI_ScrollRect BagListView; private BagTips tips; // ========== 数据 ========== private List m_items = new List(); private ItemInfo m_select; protected override void OnRunAwake() { base.OnRunAwake(); // ✅ 初始化UI组件引用 BtnClose = FindUICtrlByName("BtnClose"); BagListView = FindUICtrlByName("BagListView"); tips = BindUI("BagTips"); // ✅ 按钮事件绑定(带防重复注册保护) BtnClose.OnAddClickListener -= OnBtnClose; BtnClose.OnAddClickListener += OnBtnClose; // ✅ 列表绑定 var itemPrefab = FindUICtrlByName("Item"); BagListView.BindEvent( () => { return m_items.Count; }, (idx) => { return itemPrefab.gameObject; }, OnUpdateItem, (item) => { return item.gameObject.HFGetOrAddSimulateBehaviour(); } ); } protected override void OnOpen(Action _onOpenComplete) { base.OnOpen(_onOpenComplete); // ✅ 注册全局事件监听 HFFunCatalogue.Event.TCEvent.AddListener( enHFCTCEvent.BagItemUpdate, OnBagItemUpdate); // ✅ 初始化数据 RefreshBagItems(); } protected override void OnClose(Action _onCloseComplete) { // ✅ 取消全局事件监听 HFFunCatalogue.Event.TCEvent.RemoveListener( enHFCTCEvent.BagItemUpdate, OnBagItemUpdate); // ✅ 清理资源 tips.Clear(); base.OnClose(_onCloseComplete); } private void OnBtnClose(GameObject go) => CloseWindow(); private void OnUpdateItem(SFUI_ScrollRectItem item) { /* 更新列表项 */ } private void RefreshBagItems() { /* 刷新背包数据 */ } } ``` ### 1.2 窗口打开方式 ```csharp // 方式1:直接打开(无回调) HFFunCatalogue.UIManager.OpenWindow(); // 方式2:打开并获取窗口实例(推荐) HFFunCatalogue.UIManager.OpenWindow((win, args) => { Debug.Log("窗口打开完成"); }); // 方式3:带额外参数打开 object[] extraArgs = new object[] { "param1", 123 }; HFFunCatalogue.UIManager.OpenWindow((win, args) => { // 使用窗口实例 }, extraArgs); ``` --- ## 二、窗口生命周期 ### 2.1 生命周期方法 | 方法 | 调用时机 | 说明 | 推荐操作 | |-----|---------|------|---------| | `OnRunAwake` | 窗口创建时调用一次 | 初始化组件引用 | **绑定按钮事件、列表初始化** | | `OnOpen` | 每次打开窗口时调用 | 注册事件、刷新数据 | **注册全局TC事件、初始化数据** | | `OnClose` | 每次关闭窗口时调用 | 取消事件、清理资源 | **取消全局TC事件、清理UI状态** | | `OnDestroy` | 窗口销毁时调用 | 释放资源 | **释放非托管资源** | ### 2.2 生命周期流程图 ``` 窗口创建 ↓ OnRunAwake() ──→ 初始化组件、绑定按钮事件 ↓ 窗口打开(可多次) ↓ OnOpen() ──→ 注册TC事件、刷新数据 ↓ 窗口关闭(可多次) ↓ OnClose() ──→ 取消TC事件、清理资源 ↓ 窗口销毁 ↓ OnDestroy() ──→ 释放资源 ``` --- ## 三、窗口配置属性 ### 3.1 常用属性 | 属性 | 说明 | 默认值 | |-----|------|-------| | `isIgnoreCloseByESC` | 是否忽略ESC关闭 | false | | `isCloseOtherWindow` | 是否关闭其他窗口 | false | | `isNeedMask` | 是否需要遮罩 | true | | `maskType` | 遮罩类型 | 半透明 | ### 3.2 层叠配置 ```csharp [HFUIWindowLayer(enHFUICanvasLayer.UIWindow, enHFUIWindowLayer.Fixed, isIgnoreCloseByESC = false)] // ↑ Canvas层级 ↑ 窗口层级 ``` --- ## 四、子组件开发 ### 4.1 物品槽组件示例 ```csharp public class BagItemSlot : AbsHFUIWindow { private SFUI_Button Btn_Item; private SFUI_Image Img_Icon; private SFUI_TextMeshProUGUI Txt_Num; private Action selectCallback; private ItemInfo item; private int m_index; protected override void OnRunAwake() { base.OnRunAwake(); Btn_Item = FindUICtrlByName("Btn_Item"); Img_Icon = FindUICtrlByName("Img_Icon"); Txt_Num = FindUICtrlByName("Txt_Num"); Btn_Item.OnAddClickListener -= OnClick; Btn_Item.OnAddClickListener += OnClick; } public void SetData(ItemInfo item, ItemInfo nowSelect, int index, Action onSelect) { this.item = item; this.m_index = index; this.selectCallback = onSelect; Img_Icon.HFSetItemIcon(item.ItemConfig.Resource); Txt_Num.text = item.Info.count.ToString(); } private void OnClick(GameObject go) { selectCallback?.Invoke(item, m_index, go.transform.position); } } ``` ### 4.2 提示框组件示例 ```csharp public class BagTips : AbsHFUIWindow { private SFUI_Image Img_ItemIcon; private SFUI_TextMeshProUGUI Txt_ItemName; private SFUI_TextMeshProUGUI Txt_ItemDesc; public ItemInfo Info { get; private set; } protected override void OnRunAwake() { base.OnRunAwake(); Img_ItemIcon = FindUICtrlByName("Img_ItemIcon"); Txt_ItemName = FindUICtrlByName("Txt_ItemName"); Txt_ItemDesc = FindUICtrlByName("Txt_ItemDesc"); } public void SetData(ItemInfo item) { Info = item; Img_ItemIcon.HFSetItemIcon(item.ItemConfig.Resource); Txt_ItemName.text = item.ItemConfig.NameCN; Txt_ItemDesc.text = item.ItemConfig.DesLanguageCN; } public void Clear() { Info = null; Img_ItemIcon.HFClearSprite(); Txt_ItemName.text = string.Empty; Txt_ItemDesc.text = string.Empty; } } ``` --- **版本**: v1.1 **适用范围**: GiftGameX项目业务开发人员