您的位置:首页 > 运维架构 > 网站架构

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 这种类似移动端弹窗的架构就介绍到这来了,希望对大家有所启发和借鉴意义。哈哈。

  • 点赞
  • 收藏
  • 分享
  • 文章举报
东皇十三妖 发布了12 篇原创文章 · 获赞 0 · 访问量 931 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: