feat(ui): 添加对已存在UI页面的路由推送支持

- 在UiRouterBase中新增Push方法重载,支持直接推送已创建的IUiPageBehavior实例
- 统一页面推送逻辑到DoPushPageInternal方法,同时处理工厂创建和现有页面
- 更新Replace方法使用新的页面推送逻辑
- 优化日志输出,统一使用View.GetType().Name获取页面类型名称
- 为新功能添加完整的XML文档注释
- 在IUiRouter接口中定义新的Push方法重载签名
This commit is contained in:
GeWuYou 2026-01-19 22:00:00 +08:00
parent 859bd1de41
commit 9c27aa5927
2 changed files with 63 additions and 10 deletions

View File

@ -27,6 +27,15 @@ public interface IUiRouter : ISystem
/// <param name="policy">界面切换策略默认为Exclusive独占</param>
void Push(string uiKey, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive);
/// <summary>
/// 将已存在的UI页面压入路由栈
/// 用于预挂载节点或调试场景
/// </summary>
/// <param name="page">已创建的UI页面行为实例</param>
/// <param name="param">进入界面的参数,可为空</param>
/// <param name="policy">界面切换策略,默认为Exclusive(独占)</param>
void Push(IUiPageBehavior page, IUiPageEnterParam? param = null,
UiTransitionPolicy policy = UiTransitionPolicy.Exclusive);
/// <summary>
/// 弹出路由栈顶的UI界面返回到上一个界面

View File

@ -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);
}
/// <summary>
/// 将已存在的UI页面压入栈顶并显示
/// </summary>
/// <param name="page">已创建的UI页面行为实例</param>
/// <param name="param">页面进入参数,可为空</param>
/// <param name="policy">页面切换策略</param>
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);
}
/// <summary>
/// 弹出栈顶页面并根据策略处理页面
@ -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
}
/// <summary>
/// 执行Push的核心逻辑不触发Pipeline
/// 执行Push页面的核心逻辑统一处理
/// 这个方法同时服务于工厂创建和已存在页面两种情况
/// </summary>
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);