UIGamePanel.cs 先增加几个方法:
/* 2018.7 凉鞋的MacBook Pro (2) */ namespace QFramework.Example { public class UIGamePanelData : UIPanelData { public int LevelIndex = 1; } public partial class UIGamePanel : UIPanel { protected override void InitUI(IUIData uiData = null) { mData = uiData as UIGamePanelData ?? new UIGamePanelData(); //please add init code here Level.text = "第" + mData.LevelIndex + "关"; } protected override void ProcessMsg (int eventId,QMsg msg) { } protected override void RegisterUIEvent() { BtnPause.onClick.AddListener(() => { GamePause(); UIMgr.OpenPanel<UIGamePausePanel>(UILevel.PopUI); }); } void GameStart() { } void GamePause() { Log.E("GamePause"); } public void GameResume() { Log.E("GameResume"); } void GameOver() { } } }由于 GameResume 需要交给 UIGamePausePanel 调用。所以要做成 public 方法。
/* 2018.7 凉鞋的MacBook Pro (2) */ namespace QFramework.Example { public class UIGamePausePanelData : UIPanelData { // TODO: Query Mgr's Data } public partial class UIGamePausePanel : UIPanel { protected override void InitUI(IUIData uiData = null) { mData = uiData as UIGamePausePanelData ?? new UIGamePausePanelData(); //please add init code here } protected override void ProcessMsg (int eventId,QMsg msg) { throw new System.NotImplementedException (); } protected override void RegisterUIEvent() { BtnMain.onClick.AddListener(() => { CloseSelf(); UIMgr.ClosePanel<UIGamePanel>(); UIMgr.OpenPanel<UIMainPanel>(); }); BtnReplay.onClick.AddListener(() => { Log.E("BtnPlay Clicked"); }); BtnContinue.onClick.AddListener(() => { CloseSelf(); UIMgr.GetPanel<UIGamePanel>().GameResume(); }); } } }在 BtnContinue 中获取,这是最简单的实现。
但是从子 Panel 对象获取 父 Panel 对象,不太优雅。
这里笔者介绍一个原则:
自底向上,发消息或提供委托。
自顶向下,直接缓存引用。
同级之间,发消息。
应用到当前的例子,则为 子 Panel 应该对 父 Panel 提供委托或者发消息。
我们先实现提供委托的方式。
这个比较简单,由于 BtnContinue 其实是 public 的,所以在 UIGamePanel 打开 UIGamePausePanel 的同时就可以进行一个按钮点击事件的注册。
代码如下:
/* 2018.7 凉鞋的MacBook Pro (2) */ namespace QFramework.Example { public class UIGamePanelData : UIPanelData { public int LevelIndex = 1; } public partial class UIGamePanel : UIPanel { protected override void InitUI(IUIData uiData = null) { mData = uiData as UIGamePanelData ?? new UIGamePanelData(); //please add init code here Level.text = "第" + mData.LevelIndex + "关"; } protected override void ProcessMsg (int eventId,QMsg msg) { } protected override void RegisterUIEvent() { BtnPause.onClick.AddListener(() => { GamePause(); UIMgr.OpenPanel<UIGamePausePanel>(UILevel.PopUI).BtnContinue.onClick.AddListener(GameResume); }); } void GameStart() { } void GamePause() { Log.E("GamePause"); } void GameResume() { Log.E("GameResume"); } void GameOver() { } } }代码很简单,这要在 BtnPause 按钮点击时,进行 BtnContinue 的点击事件注册。
Button 的 onClick 事件,不用担心会被覆盖,因为用的是 AddListener 这个 API,是增加,实质上类似于 += 操作。这样就可以把事件从外部注入到 UIGamePausePanel 中。
这也是比较方便的一种方式,尤其是在 Dialog 或者 Prompt 通用的时候,其标记过的控件都可以在外边访问。
这样有利有弊,有点不符合面向对象的设计原则,不过问题不大。
这样第二种方式就完成了。
第三种方式则是通过发送消息,UIGamePausePanel 可以把事件发送给 UIGamePanel。
首先要在 UIGamePanel 中进行事件的定义:
public enum UIGamePanelEvent { Start = QMgrID.UI, GameResume, End }