zoukankan      html  css  js  c++  java
  • 通过命令模式搭建一个UI框架

    先编写一个UI基类统一一些界面的逻辑行为:

    public class BaseUI : MonoBehaviour 
    {
        
        /// <summary>
        /// 当前界面名称
        /// </summary>
        [HideInInspector]
        public string UIName;
    
        private Transform mTransform;
        public Transform CacheTransform
        {
            get
            {
                if (mTransform == null) mTransform = this.transform;
                return mTransform;
            }
        }
    
        private GameObject mGo;
        public GameObject CacheGameObject
        {
            get
            {
                if (mGo == null) mGo = this.gameObject;
                return mGo;
            }
        }
    
        /// <summary>
        /// 显示当前UI
        /// </summary>
        /// <param name="param">附加参数</param>
        public void Show(object param)
        {
            CacheGameObject.SetActive(true);
            OnShow(param);
        }
    
        /// <summary>
        /// 隐藏当前界面
        /// </summary>
        public void Hide()
        {
            CacheGameObject.SetActive(false);
            OnHide();
        }
    
        [HideInInspector]
        public Canvas mainCanvas = null;
    
        /// <summary>
        /// 绑定脚本并且激活游戏物体会调用的方法
        /// </summary>
        void Awake() 
        {
            OnAwake();
        }
    
        /// <summary>
        /// 初始化UI主要用于寻找组件等
        /// </summary>
        public void UIInit()
        {
            if (mainCanvas == null)
            {
                mainCanvas = this.GetComponent<Canvas>();
            }
            if (mainCanvas != null)
            {
                mainCanvas.worldCamera = AppMgr.Instance.MainCamera;
            }
            mainCanvas.sortingOrder = UIDef.GetUIOrderLayer(UIName);
            OnInit();
        }
    
        /// <summary>
        /// 初始化当前界面
        /// </summary>
        protected virtual void OnInit() { }
        protected virtual void OnAwake() { }
    
        /// <summary>
        /// 显示当前界面
        /// </summary>
        /// <param name="param">附加参数</param>
        protected virtual void OnShow(object param) { }
    
        /// <summary>
        /// 隐藏当前界面
        /// </summary>
        protected virtual void OnHide() { }
        /// <summary>
        /// 删除当前UI 
        /// </summary>
        protected virtual void OnDestroy() { }
    }

    命令数据结构类,这里面保存了对UI操作的命令:uiName 要操作的UI的名称,Type 要绑定的脚本类型,listener加载完成后的回调,param要传入的参数, cmdType 命令类型。

     /// <summary>
        /// 操作UI命令集
        /// </summary>
        public class Command
        {
            /// <summary>
            /// 命令类型
            /// </summary>
            public enum CmdType
            {
                /// <summary>
                /// 创建
                /// </summary>
                CreateAndShow,
                /// <summary>
                /// 创建
                /// </summary>
                Create,
                /// <summary>
                /// 显示或者刷新
                /// </summary>
                Show,
                /// <summary>
                /// 隐藏
                /// </summary>
                Hide,
                /// <summary>
                /// 删除
                /// </summary>
                Destroy,
            }
    
            /// <summary>
            /// UI名称
            /// </summary>
            public string uiName;
    
            /// <summary>
            /// 要绑定的脚本
            /// </summary>
            public Type type;
    
            /// <summary>
            /// 加载完成之后的回调
            /// </summary>
            public ILoadUIListener listener;
    
            /// <summary>
            /// 要传入的数据
            /// </summary>
            public object param;
    
            /// <summary>
            /// 命令类型
            /// </summary>
            public CmdType cmdType;
    
            /// <summary>
            /// 创建时候需要回调
            /// </summary>
            public bool createCanCall = true;
    
            /// <summary>
            /// 获取一个显示的命令
            /// </summary>
            /// <param name="_uiName">UI名称</param>
            /// <param name="_param">要传入的参数</param>
            public static Command CreateAndShowCmd(string uiName, Type type, ILoadUIListener listener, object param , bool createCanCall)
            {
                Command cmd = new Command(CmdType.CreateAndShow, uiName, type);
                cmd.createCanCall = createCanCall;
                cmd.listener = listener;
                cmd.type = type;
                cmd.param = param;
                return cmd;
            }
            /// <summary>
            /// 获取一个显示的命令
            /// </summary>
            /// <param name="_uiName">UI名称</param>
            /// <param name="_param">要传入的参数</param>
            public static Command ShowCmd(string _uiName,ILoadUIListener listener ,object _param, bool _createCanCall)
            {
                Command cmd = new Command(CmdType.Show, _uiName, _param);
                cmd.createCanCall = _createCanCall;
                cmd.listener = listener;
                return cmd;
            }
    
    
            /// <summary>
            /// 获取一个创建的命令
            /// </summary>
            /// <param name="_type">要绑定的脚本</param>
            /// <param name="_listener">加载完成之后的回调</param>
            public static Command CreateCmd(Type _type,string _uiName, ILoadUIListener _listener)
            {
                return new Command(CmdType.Create, _uiName, _type, _listener);
            }
    
            /// <summary>
            /// 获取一个隐藏命令
            /// </summary>
            /// <param name="_uiName">要隐藏的UI名称</param>
            /// <returns></returns>
            public static Command HideCmd(string _uiName)
            {
                return new Command(CmdType.Hide, _uiName,null);
            }
    
            /// <summary>
            /// 获取一个删除的命令
            /// </summary>
            /// <param name="_uiName">UI名称</param>
            /// <returns></returns>
            public static Command DestroyCmd(string _uiName)
            {
                return new Command(CmdType.Destroy, _uiName, null);
            }
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="_cmdType">命令类型</param>
            /// <param name="_uiName">UI名称</param>
            /// <param name="_param">要传入的参数</param>
            public Command(CmdType _cmdType, string _uiName, object _param)
            {
                uiName = _uiName;
                cmdType = _cmdType;
                param = _param;
            }
    
            /// <summary>
            /// 构造
            /// </summary>
            /// <param name="_cmdType">命令类型</param>
            /// <param name="_type">要绑定的脚本</param>
            /// <param name="_listener">加载完成之后的回调</param>
            public Command(CmdType _cmdType,string _uiName,Type _type,ILoadUIListener _listener)
            {
                cmdType = _cmdType;
                type = _type;
                listener = _listener;
                uiName = _uiName;
            }
        }

    编写UIMgr ,管理各个UI的通用操作 ,打开、关闭、返回等

    public class UIMgr : EventNode 
    {
        private static UIMgr mInstance;
        public static UIMgr Instance
        {
            get
            {
                return mInstance;
            }
        }

    这是一个单例模式,接下来创建用来存储UI缓存的字典,UIMgr也是围绕着这个字典进行维护

    /// <summary>
        /// 所有UI
        /// </summary>
        private Dictionary<string, BaseUI> mDicUI = new Dictionary<string, BaseUI>();

    接下来需要提供一些功能函数:

     /// <summary>
        /// 添加一个UI
        /// </summary>
        /// <param name="ui"></param>
        public void AddUI(BaseUI ui)
        {
            if (ui != null)
            {
                mDicUI[ui.UIName] = ui;
                
            }
            
        }
    
        /// <summary>
        /// 移除一个UI
        /// </summary>
        /// <param name="ui"></param>
        public void RemoveUI(BaseUI ui)
        {
            if (ui != null && mDicUI.ContainsKey(ui.UIName))
            {
                mDicUI.Remove(ui.UIName);
            }
        }
    /// <summary>
        /// 所有命令集合
        /// </summary>
        public List<Command> cmdList = new List<Command>();
    
        internal Transform UIROOT = null;
        void Awake() 
        {
            UIROOT = this.transform.FindChild("UIRoot");
            mInstance = this;
            DontDestroyOnLoad(this.gameObject);
        }
    
        public List<string> GetCurrentOpenUI()
        {
            List<string> list = new List<string>();
           foreach(BaseUI ui in mDicUI.Values)
           {
               if (ui.CacheGameObject.activeInHierarchy)
               {
                   list.Add(ui.UIName);
               }
           }
           return list;
        }

    提供基于命令的UI操作

    #region 创建UI
    
        /// <summary>
        /// 创建UI
        /// </summary>
        /// <param name="uiName">UI名称</param>
        /// <param name="type">要绑定的脚本</param>
        /// <param name="listener">创建完成的回调</param>
        public void CreateUI(string uiName, Type type, ILoadUIListener listener)
        {
            cmdList.Add(Command.CreateCmd(type,uiName,listener));
        }
    
        /// <summary>
        /// 创建UI的实体部分
        /// </summary>
        /// <param name="cmd">命令</param>
        private void _Create(Command cmd)
        {
           
            BaseUI ui= null;
            mDicUI.TryGetValue(cmd.uiName, out ui);
            if (ui != null)
            {
                if (cmd.listener != null) cmd.listener.FiniSh(ui);
            }
            else
            {
    
                ResMgr.Instance.Load(cmd.uiName,new LoadResFinish(cmd),typeof(GameObject),true);
            }
        }
    
        #endregion
    
        #region 显示UI
    
        /// <summary>
        /// 显示一个UI界面  如果不存在就创建
        /// </summary>
        /// <param name="uiName">ui名称</param>
        /// <param name="type">要绑定的脚本</param>
        /// <param name="listener">如果界面不存在则会有界面加载完成后的回调</param>
        /// <param name="param">要传入的参数</param>
        public void ShowUI(string uiName, Type type, ILoadUIListener listener,object param = null,bool createCanCall = false)
        {
            BaseUI ui = null;
            mDicUI.TryGetValue(uiName,out ui);
            if (ui == null)
            {
                cmdList.Add(Command.CreateAndShowCmd(uiName,type,listener, param, createCanCall));
            }
            else
            {
                cmdList.Add(Command.ShowCmd(uiName, listener, param, createCanCall));
            }
            
            
        }
    
        /// <summary>
        /// 显示一个界面
        /// </summary>
        /// <param name="cmd"></param>
        private void _ShowUI(Command cmd)
        {
    
            BaseUI ui = null;
            mDicUI.TryGetValue(cmd.uiName, out ui);
            if (ui != null)
            {
                if (cmd.listener != null)
                {
                    cmd.listener.FiniSh(ui);
                }
                ui.Show(cmd.param);
                
            }
        }
    
       
        #endregion
    
        #region  隐藏UI
    
        /// <summary>
        /// 隐藏这个UI
        /// </summary>
        /// <param name="uiName"></param>
        public void HideUI(string uiName)
        {
            
            cmdList.Add(Command.HideCmd(uiName));
        }
    
    
        private void _HideUI(Command cmd)
        {
            BaseUI ui = null;
            mDicUI.TryGetValue(cmd.uiName, out ui);
            if (ui != null)
            {
                ui.Hide();
            }
        }
    #endregion
    
        #region  删除UI
    
        /// <summary>
        /// 删除UI
        /// </summary>
        /// <param name="uiName">UI名称</param>
        public void DestroyUI(string uiName)
        {
            cmdList.Add(Command.DestroyCmd(uiName));
        }
    
        private void _DestroyUI(Command cmd)
        {
            BaseUI ui = null;
            mDicUI.TryGetValue(cmd.uiName, out ui);
            if (ui != null)
            {
                mDicUI.Remove(ui.UIName);
                Destroy(ui.CacheGameObject);
            }
        }
    
        #endregion

    在Update中执行操作命令

    void Update() 
        {
    
            if (cmdList.Count > 0)
            {
                Command tempCmd = null;
                tempCmd = cmdList[0];
                if (tempCmd == null)
                {
                    cmdList.RemoveAt(0);
                }
                else
                {
                    switch(tempCmd.cmdType)
                    {
                        case Command.CmdType.CreateAndShow:
    
                            _Create(tempCmd);
                            break;
                        case Command.CmdType.Create:
                            _Create(tempCmd);
                            break;
                        case Command.CmdType.Destroy:
                            _DestroyUI(tempCmd);
                            break;
                        case Command.CmdType.Hide:
                            
                            _HideUI(tempCmd);
                            break;
                        case Command.CmdType.Show:
                            _ShowUI(tempCmd);
                            break;
                    }
                    cmdList.RemoveAt(0);
                }
            }
        }

    资源加载完成后的回调 

    /// <summary>
        /// UI资源加载完成的回调
        /// </summary>
        public class LoadResFinish : IResLoadListener
        {
            /// <summary>
            /// 命令
            /// </summary>
            public Command cmd;
            public LoadResFinish(Command _cmd)
            {
                cmd = _cmd;
            }
    
            public void Finish(object asset)
            {
    
                if (cmd == null)
                {
                    return;
                }
                GameObject go = Instantiate<GameObject>(asset as GameObject);
                go.SetActive(false);
                BaseUI ui =  go.AddComponent(cmd.type) as BaseUI;
                ui.UIName = cmd.uiName;
                go.gameObject.name = ui.UIName;
                ui.CacheTransform.SetParent(UIMgr.Instance.UIROOT, false);
                UIMgr.Instance.AddUI(ui);
                if (cmd.cmdType == Command.CmdType.CreateAndShow)
                {
                    UIMgr.Instance.ShowUI(cmd.uiName, cmd.type, cmd.listener, cmd.param, cmd.createCanCall);
                }
                else if (cmd.createCanCall && cmd.listener != null)
                {
                    cmd.listener.FiniSh(ui);
                }
    
                ui.UIInit();
            }
    
            public void Failure()
            {
                if (cmd.createCanCall && cmd.listener != null)
                {
                    cmd.listener.Failure();
                }
            }
        }
  • 相关阅读:
    SQL_Server_2005_启用远程连接
    Oracle外网或内网远程连接
    还原数据库到指定时间点
    SQL Server账号密码(sa)登录失败 错误原因:18456
    sql server如何设置密码过期时间呢?
    安装SQL Server2014 :规则”Windows Management Instrumentation (WMI)服务 “失败
    impala
    dolphinscheduler
    829. Consecutive Numbers Sum 连续的数字求和
    472. Concatenated Words 查找自己拼出来的单词 反向word break
  • 原文地址:https://www.cnblogs.com/bambomtan/p/5011881.html
Copyright © 2011-2022 走看看