5.UI架构 弹窗管理器
作者:互联网
仿照移动端的弹窗机制写的UI架构:所有的UI窗口 在加载后都注入到弹窗管理器中进行管理开关和赋值显示。
代码架构: 1 弹窗父类Activity 2. 具体弹窗类 xxActivtiy .3.弹窗管理器AcitivtiyManger.4,传递数据类 bundle.5 加载注入类 LoadInUI.6.数据信息接受控制类xxUIController.
具体代码:
1 弹窗父类Activity :
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:
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:
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:
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中:
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 这种类似移动端弹窗的架构就介绍到这来了,希望对大家有所启发和借鉴意义。哈哈。
标签:管理器,windows,void,BSM,UI,key,container,public,弹窗 来源: https://blog.csdn.net/s_xiajunjun1986/article/details/101025463