From 9c27aa5927c5fd6861a982fccfb4aa4d03c5433b Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:00:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E5=B7=B2=E5=AD=98=E5=9C=A8UI=E9=A1=B5=E9=9D=A2=E7=9A=84?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E6=8E=A8=E9=80=81=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在UiRouterBase中新增Push方法重载,支持直接推送已创建的IUiPageBehavior实例 - 统一页面推送逻辑到DoPushPageInternal方法,同时处理工厂创建和现有页面 - 更新Replace方法使用新的页面推送逻辑 - 优化日志输出,统一使用View.GetType().Name获取页面类型名称 - 为新功能添加完整的XML文档注释 - 在IUiRouter接口中定义新的Push方法重载签名 --- GFramework.Game.Abstractions/ui/IUiRouter.cs | 9 +++ GFramework.Game/ui/UiRouterBase.cs | 64 +++++++++++++++++--- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/GFramework.Game.Abstractions/ui/IUiRouter.cs b/GFramework.Game.Abstractions/ui/IUiRouter.cs index e311bad..c942344 100644 --- a/GFramework.Game.Abstractions/ui/IUiRouter.cs +++ b/GFramework.Game.Abstractions/ui/IUiRouter.cs @@ -27,6 +27,15 @@ public interface IUiRouter : ISystem /// 界面切换策略,默认为Exclusive(独占) void Push(string uiKey, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive); + /// + /// 将已存在的UI页面压入路由栈 + /// 用于预挂载节点或调试场景 + /// + /// 已创建的UI页面行为实例 + /// 进入界面的参数,可为空 + /// 界面切换策略,默认为Exclusive(独占) + void Push(IUiPageBehavior page, IUiPageEnterParam? param = null, + UiTransitionPolicy policy = UiTransitionPolicy.Exclusive); /// /// 弹出路由栈顶的UI界面,返回到上一个界面 diff --git a/GFramework.Game/ui/UiRouterBase.cs b/GFramework.Game/ui/UiRouterBase.cs index d776a2e..6733713 100644 --- a/GFramework.Game/ui/UiRouterBase.cs +++ b/GFramework.Game/ui/UiRouterBase.cs @@ -85,10 +85,47 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter ); BeforeChange(@event); - DoPushInternal(uiKey, param, policy); + + // 先创建页面,然后使用统一的Push逻辑 + var page = _factory.Create(uiKey); + Log.Debug("Create UI Page instance: {0}", page.GetType().Name); + + DoPushPageInternal(page, param, policy); + AfterChange(@event); } + /// + /// 将已存在的UI页面压入栈顶并显示 + /// + /// 已创建的UI页面行为实例 + /// 页面进入参数,可为空 + /// 页面切换策略 + public void Push( + IUiPageBehavior page, + IUiPageEnterParam? param = null, + UiTransitionPolicy policy = UiTransitionPolicy.Exclusive + ) + { + var uiKey = page.View.GetType().Name; + + if (IsTop(uiKey)) + { + Log.Warn("Push ignored: UI already on top: {0}", uiKey); + return; + } + + var @event = CreateEvent(uiKey, UiTransitionType.Push, policy, param); + + Log.Debug( + "Push existing UI Page: key={0}, policy={1}, stackBefore={2}", + uiKey, policy, _stack.Count + ); + + BeforeChange(@event); + DoPushPageInternal(page, param, policy); + AfterChange(@event); + } /// /// 弹出栈顶页面并根据策略处理页面 @@ -139,7 +176,10 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter // 使用内部方法,避免触发额外的Pipeline DoClearInternal(popPolicy); - DoPushInternal(uiKey, param, pushPolicy); + + var page = _factory.Create(uiKey); + Log.Debug("Create UI Page instance for Replace: {0}", page.GetType().Name); + DoPushPageInternal(page, param, pushPolicy); AfterChange(@event); } @@ -264,32 +304,36 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 执行Push的核心逻辑(不触发Pipeline) + /// 执行Push页面的核心逻辑(统一处理) + /// 这个方法同时服务于工厂创建和已存在页面两种情况 /// - private void DoPushInternal(string uiKey, IUiPageEnterParam? param, UiTransitionPolicy policy) + private void DoPushPageInternal(IUiPageBehavior page, IUiPageEnterParam? param, UiTransitionPolicy policy) { + // 1. 处理当前栈顶页面 if (_stack.Count > 0) { var current = _stack.Peek(); - Log.Debug("Pause current page: {0}", current.GetType().Name); + Log.Debug("Pause current page: {0}", current.View.GetType().Name); current.OnPause(); if (policy == UiTransitionPolicy.Exclusive) { - Log.Debug("Hide current page (Exclusive): {0}", current.GetType().Name); + Log.Debug("Hide current page (Exclusive): {0}", current.View.GetType().Name); current.OnHide(); } } - var page = _factory.Create(uiKey); - Log.Debug("Create UI Page instance: {0}", page.GetType().Name); - + // 2. 将新页面添加到UiRoot + Log.Debug("Add page to UiRoot: {0}", page.View.GetType().Name); _uiRoot.AddUiPage(page); + + // 3. 压入栈 _stack.Push(page); + // 4. 触发页面生命周期 Log.Debug( "Enter & Show page: {0}, stackAfter={1}", - page.GetType().Name, _stack.Count + page.View.GetType().Name, _stack.Count ); page.OnEnter(param);