其他分享
首页 > 其他分享> > 5.UI架构 弹窗管理器

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