5.UI架构 弹窗管理器
2020-02-02 11:54
1746 查看
仿照移动端的弹窗机制写的UI架构:所有的UI窗口 在加载后都注入到弹窗管理器中进行管理开关和赋值显示。
代码架构: 1 弹窗父类Activity 2. 具体弹窗类 xxActivtiy .3.弹窗管理器AcitivtiyManger.4,传递数据类 bundle.5 加载注入类 LoadInUI.6.数据信息接受控制类xxUIController.
具体代码:
1 弹窗父类Activity :
[code]using System.Collections; using System.Collections.Generic; using UnityEngine; public class Activity : MonoBehaviour { //UI弹窗管理器 public ActivityManager manager; //UI弹窗入口 public virtual void OnCreate(Bundle _bundle = null) { } //暂停 public virtual void OnPause() { } //重置 public virtual void OnResume(Bundle _bundle = null) { } //退出 public virtual void OnActivityDestory() { } }
2. 具体弹窗类 xxActivtiy继承Activity:
[code]using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public enum CurrentPanel { Image_Buy, Image_Seal, Image_Make } //商店弹窗 public class MarketActivity : Activity { [Header("关闭按钮")] public Image bg; public Button close; public Toggle Buy; public Toggle Seal; public Toggle Make; public GameObject imageBg; //商店等级 public Text Lv; public Text adress; /// <summary> /// 价格波动 刷新时间 /// </summary> public Text time; /// <summary> /// 补货 刷新时间 /// </summary> public Text time_1; /// <summary> /// 今日最大出售金额 /// </summary> public Text seal_Max; //记录当前是 购买 、 卖出 还是 制作 面板 [HideInInspector] public CurrentPanel current = CurrentPanel.Image_Buy; [Header("Buy, Seal , Make 父物体")] public GameObject[] BSM; //商店主界面进入 public override void OnCreate(Bundle _bundle = null) { #region // 商店主界面的相关设置绑定刷新赋值以及网络信息的监听操作 //关菊花 GameManager.Instance.activity.Flush(); //关闭3d主场景输入控制系统 GameManager.Instance.inputSystem.SetActiveState(false); this.gameObject.SetActive(true); //添加购买成功监听 GameManager.Instance.gameEventDispatcher.AddEventListener(GameEventType.MarketBuySuccess, BuySuccess); close.onClick.AddListener(CloseMarketOnClick); Buy.onValueChanged.AddListener(delegate (bool isOn) { ValueChange(isOn, Buy); }); //刷新界面 RefreshPanel(); SetValues(); //关闭主界面输入控制系统 GameManager.Instance.inputSystem.SetActiveState(false); #endregion } //商店主界面重置 public override void OnResume(Bundle _bundle = null) { base.OnResume(_bundle); Debug.Log("OnResume调用了"); SetValues(); } //退出商店总界面 public override void OnActivityDestory() { #region//退出主界面的一系列关闭 清空 解除绑定操作。 Debug.Log("退出敞口"); base.OnActivityDestory(); GameManager.Instance.gameEventDispatcher.RemoveEventListener(GameEventType.MarketBuySuccess, BuySuccess); close.onClick.RemoveAllListeners(); gameObject.SetActive(false); GameManager.Instance.inputSystem.SetActiveState(true); #endregion } //返回按钮 void CloseMarketOnClick() { manager.PopWindow(); } //商店内几个界面的切换 void ValueChange(bool isOn, Toggle _toggle) { if (!isOn || _toggle.name == current.ToString()) { return; } else { //买商品的界面 if (_toggle.name == "Image_Buy") { current = CurrentPanel.Image_Buy; Buy.isOn = true; Seal.isOn = false; Make.isOn = false; if (GameManager.Instance.locLimit == LocationLimit.Open) Session.SendQueryMarketMessage(int.Parse(AndroidSDK.GetAddress()[2])); else Session.SendQueryMarketMessage(GameInstance.heroDate.areaCode); ActivieObject(BSM[0].name); BSM[0].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().ShowElement(4); } //卖商品的界面 else if (_toggle.name == "Image_Seal") { current = CurrentPanel.Image_Seal; Buy.isOn = false; Seal.isOn = true; Make.isOn = false; #region 7.3 该资源商店 销售界面刷新问题 if (GameManager.Instance.locLimit == LocationLimit.Open) Session.SendQuerySealListMessage(int.Parse(AndroidSDK.GetAddress()[2])); else Session.SendQuerySealListMessage(GameInstance.heroDate.areaCode); #endregion if (MainPanelContrller.Instance.openStyle == OpenMarketStyle.Skill) { // ActivieObject(yuanwai_BSM[1].name); yuanwai_BSM[1].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().changePanel = false; // Debug.Log("changePanel" + yuanwai_BSM[1].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().changePanel); //yuanwai_BSM[1].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().ShowElement(4); } else { ActivieObject(BSM[1].name); BSM[1].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().ShowElement(4); } } //制作商品的解密 else if (_toggle.name == "Image_Make") { current = CurrentPanel.Image_Make; Buy.isOn = false; Seal.isOn = false; Make.isOn = true; ActivieObject(BSM[2].name); //查制作列表 if (GameManager.Instance.locLimit == LocationLimit.Open) Session.SendQueryMakeListMessage(int.Parse(AndroidSDK.GetAddress()[2])); else Session.SendQueryMakeListMessage(GameInstance.heroDate.areaCode); //制造界面相同 BSM[2].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().changePanel = false; BSM[2].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().ShowElement(4); } } } void ActivieObject(string go) { for (int i = 0; i < BSM.Length; i++) { if (BSM[i].name == go) BSM[i].SetActive(true); else BSM[i].SetActive(false); } } //开启界面赋值 void SetValues() { //获取本地数据 GameManager.Instance.allXmlData.GetXmlData<LocalizeData>(config, 12001, ref xml_data); UpdateSealMax(GameInstance.marketMaxSeal); //Debug.Log ("current" + current); Debug.Log("SetValues() 此方法执行了"); if (current == CurrentPanel.Image_Buy) { BSM[0].transform.GetChild(1).GetComponentInChildren<MarketLayoutGroup>().SetAmount(GameInstance.marketGoods.Count); } else if (current == CurrentPanel.Image_Seal) { ActivieObject(yuanwai_BSM[1].name); BSM[1].transform.GetChild(1).GetComponentInChildren<MarketLayoutGroup>().SetAmount(GameInstance.marketSeals.Count); } } /// <summary> /// 刷新界面 /// </summary> void RefreshPanel() { if (current == CurrentPanel.Image_Buy) { ActivieObject(BSM[0].name); BSM[0].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().ShowElement(4); } if (current == CurrentPanel.Image_Seal) { ActivieObject(BSM[1].name); BSM[1].transform.GetChild(2).GetComponentInChildren<MarketLayoutGroup>().ShowElement(4); } } }
3.弹窗管理器AcitivtiyManger:
[code]using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class ActivityManager : BaseSingleton<ActivityManager> { //activity实例到储存器 Dictionary<Type, Activity> cache; Stack<Activity> windows; public ActivityManager() { cache = new Dictionary<Type, Activity>(); windows = new Stack<Activity>(); } //注入activity实例到储存器 public void AddActivity(Activity act) { Type t = act.GetType(); if (!cache.ContainsKey(t)) { cache.Add(t, act); act.manager = this; } else { Debug.LogError("Can NOT add same key"); } } //获取对应的activity实例,并且传入Boundle类型参数调用其入口函数 public void PushWindow(Type t, Bundle _bundle = null) { Activity temp = cache[t]; if (windows.Count != 0) { Type topType = windows.Peek().GetType(); //如果栈顶是当前需要获取的activity实例,则调用activity实例 if (t == topType) { temp.OnCreate(_bundle); return; } else { //让当前窗口不可操作,等待需求窗口压如后弹窗 Activity old = windows.Peek(); old.OnPause(); } } //activity实例压入栈 windows.Push(temp); //用activity实例,传入bundle类型的参数 temp.OnCreate(_bundle); } /// <summary> /// 顶部弹框是否是此类型弹框 /// </summary> /// <param name="t"></param> /// <returns></returns> public bool IsPushWindow(Type t) { bool temp = false; if (windows.Count != 0 && cache.ContainsKey(t)) { Activity top = windows.Peek(); Activity need = cache[t]; if (top == need) temp = true; } return temp; } /// <summary> /// 关闭指定类型 /// </summary> /// <param name="t"></param> /// <param name="_bundle"></param> public void PopWindow(Type t, Bundle _bundle = null) { JumpToActivity(t, _bundle); PopWindow(); //AudioManager.Instance.PlayFX ("fx_closewindow",true); } public void PopWindow(Bundle i = null) { if (windows.Count == 0) { Debug.LogError("Pop Failed, No enough Window"); return; } //出栈 Activity current = windows.Pop(); current.OnActivityDestory(); //AudioManager.Instance.PlayFX ("fx_closewindow",true); if (windows.Count > 0) { Activity next = windows.Peek(); next.OnResume(i); } } /// <summary> /// 销毁所有的窗口 /// </summary> public void Flush() { //关闭窗口的声音 if (windows.Count != 0) { AudioManager.Instance.PlayFX("fx_closewindow", true); } //销毁全部窗口实例 while (windows.Count != 0) { Activity ac = windows.Pop(); ac.OnActivityDestory(); } } /// <summary> /// 跳到指定窗口 /// </summary> /// <param name="target">Target.</param> public void JumpToActivity(Type target, Bundle bundle = null) { if (cache.ContainsKey(target)) { Activity ac = cache[target]; //判断是否在堆栈里 if (windows.Contains(ac)) { //新建一个队列 用于占时储存重栈中移除的非目标Activity,然后在装进栈,这样目标acitivity就在栈,直接调用关闭。 Queue<Activity> temp = new Queue<Activity>(); Activity current = windows.Pop(); current.OnPause(); while (current != ac) { temp.Enqueue(current); current = windows.Pop(); } while (temp.Count > 0) { Activity a = temp.Dequeue(); windows.Push(a); } windows.Push(current); ac.OnResume(bundle); } else { //没有入栈 PushWindow(target, bundle); } } else { Debug.LogError("Type is NOT Load"); } } /// <summary> /// 得到栈顶的窗口 /// </summary> /// <returns>The current top activity.</returns> public Activity GetCurrentTopActivity() { return windows.Peek(); } private void MakeRenderOrderRight(Activity a) { a.transform.SetAsLastSibling(); } }
4 .参赛类型Boudle:
[code]using System.Collections; using System.Collections.Generic; using UnityEngine; public class Bundle { Dictionary<string , object> obj_container; Dictionary<string , bool> bool_container; Dictionary<string , string> string_container; Dictionary<string , int> int_containder; public void PutObject(string key , object o) { if(obj_container == null) { obj_container = new Dictionary<string, object> (); } if(obj_container.ContainsKey(key)) { Debug.LogError ("Key have been USED"); return; } obj_container.Add (key,o); } public object GetObject(string key) { if (obj_container.ContainsKey (key)) return obj_container [key]; else { Debug.LogError ("Key is illegal"); return null; } } /// <summary> /// 给数据放入布尔值 /// </summary> /// <param name="key">Key.</param> /// <param name="_value">If set to <c>true</c> value.</param> public void PutBoolean(string key , bool _value) { if(bool_container == null) { bool_container = new Dictionary<string, bool> (); } if(bool_container.ContainsKey(key)) { Debug.LogError ("Key have been USED"); return; } bool_container.Add (key,_value); } public bool GetBoolean(string _key) { if (bool_container.ContainsKey (_key)) { return bool_container [_key]; } else { Debug.LogError ("Key is illegal"); return false; } } /// <summary> /// 给Bundle放入字符串 /// </summary> /// <param name="_key">Key.</param> /// <param name="_value">Value.</param> public void PutString(string _key , string _value) { if(string_container == null) { string_container = new Dictionary<string, string> (); } if(string_container.ContainsKey(_key)) { Debug.LogError ("Key have been USED"); return; } string_container.Add (_key,_value); } public string GetString(string _key) { if(string_container.ContainsKey(_key)) { return string_container[_key]; } else { Debug.LogError ("Key is illegal"); return string.Empty; } } public void PutInt(string _key , int _value) { if(int_containder == null) { int_containder = new Dictionary<string, int> (); } if(int_containder.ContainsKey(_key)) { Debug.LogError ("Key have been USED"); return; } int_containder.Add (_key,_value); } public int GetInt(string _key) { if (int_containder.ContainsKey (_key)) { return int_containder [_key]; } else { Debug.LogError ("Key is illegal"); return -1; } } }
5.加载弹窗实例xxActivity并且注入到管理器ActivityManger中:
[code]public class LoadINUI { ActivityManger acitivityManger; GameObject acivityObj; public GameObject LoadActivityObject(string name) { acivityObj = Resources.Load<GameObject>(name); acivityObj.AddComponent<MarketActivity>(); //注入 acitivityManger.PushWindow(typeof(MarketActivity)); return acivityObj; } }
6..数据信息接受控制类xxUIController.就是在接受到信息后调用LoadInUI加载和注入Acitivity实例后调用其入口函数,依据获得的信息显示在界面上。
OK 这种类似移动端弹窗的架构就介绍到这来了,希望对大家有所启发和借鉴意义。哈哈。
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- JPDA 架构研究21 - JDI的Debugger的UI部分
- iOS架构设计(解耦的尝试)之UI样式复用与布局管理
- Unity使用ECS架构entitas实现ui响应及回放系统
- 任务1:创建核心UI架构——创建所需要的Activity
- 三层架构,先做后台,然后对接UI。
- ASP.NET的三层架构(DAL,BLL,UI)
- 三层架构(UI/BLL/DAL)
- UI动画架构(上下滚动,里面View可以实现动画<透明,移动,缩放,变色>l)
- SharePoint 2010 UI 定制化系列之定制Ribbon: Server Ribbon 架构的探讨和理解
- ASP.NET的三层架构(DAL,BLL,UI)
- JQuery Smart UI 简介(五) — 框架设计【前篇】(前台UI层架构)
- 【转】Unity3D-深入剖析NGUI的游戏UI架构
- html结合qt混合ui交互架构
- 魅族M8 UI新架构
- 架构、引擎与UI通用语言解释
- MFC原创:三层架构02(人事管理系统)UI-01
- 基于组件方式的游戏UI架构设计
- 转 Unity3D-深入剖析NGUI的游戏UI架构
- ASP.NET的三层架构(DAL,BLL,UI)
- 了解c#中的三层架构(DAL,BLL,UI)