在 ILRuntime 的基础上,搭建一个简单的UI系统(二)UIView

上一篇主要处理了一些UIPanel相关的逻辑,这一篇我们主要来讲讲UIView部分的理解。

目前个人理解下来UIView主要有两种情况

1.例如商城界面,会有很多的物品卡,每一个物品卡就是一个UIView,然后我们在UIView中进行物品的详情显示等逻辑。(这种情况一般是动态加载物品卡的prefab)

2.在一些组件较多的复杂界面,例如个人信息界面可能会有好几个标签页,如果这些组件逻辑全部写在一个UIPanel中,那么这个UIPanel的代码将会很长,看着很头疼。因此我们可以将其分成几个UIView,然后在UIView当中再去写单独的逻辑。(这种情况一般组件已经挂载在UIPanel上了)

 

注:由于代码量较大,改动较多,有兴趣的小伙伴还是看github上面的工程吧,有好的建议可以提出。

由于有的组件需要动态添加,有的是已经加载好挂在UIPanel中的,因此我们会在UIView中添加一个GameObject变量,用于存储UIView对应的GameObject。(考虑下来之前的url属性暂时只有在UIPanel中用到,所以将其移到UIPanel中)

namespace Hotfix.UI
{
    public class UIView : IView
    {
        public GameObject gameObject { private set; get; }
        public Transform transform { private set; get; }
        public RectTransform rectTransform { private set; get; }

        Transform m_parent;
        public Transform parent
        {
            get { return m_parent; }
            set
            {
                m_parent = value;
                if (m_parent != null)
                    transform?.SetParent(m_parent);
            }
        }

        ......


        public UIView()
        {
        }

        public UIView(GameObject go)
        {
            SetGameObject(go);
        }

        public UIView(GameObject go, Transform parent)
        {
            SetGameObject(go, parent);
        }

        protected void SetGameObject(GameObject go, Transform parent = null)
        {
            gameObject = go;
            if (gameObject == null)
                return;
            transform = gameObject.transform;
            rectTransform = gameObject.GetComponent<RectTransform>();
            this.parent = parent;
        }

        public void SetActive(bool isActive)
        {
            if (isActive)
                Show();
            else
                Hide();
        }

        public virtual void Init()
        {
            GetChild();
        }

        public virtual void GetChild()
        {
        }

        ......
    }
}

我们在UIViewManager中来实例化UIView,并且管理对应的生命周期。

namespace Hotfix.Manager
{
    public class UIViewManager : ManagerBase<UIViewManager>
    {
        ......

        public T CreateView<T>(GameObject go) where T : UIView
        {
            return CreateView(typeof(T), go) as T;
        }

        public T CreateView<T>(GameObject go, RectTransform parent) where T : UIView
        {
            return CreateView(typeof(T), go, parent) as T;
        }

        //创建UIView
        public UIView CreateView(Type type, params object[] args)
        {
            UIView view = Activator.CreateInstance(type, args) as UIView;
            view.Init();
            AddUIView(view);
            return view;
        }
        
        ......

    }
}

商城的物品卡组件GoodsItemView,由于是动态加载的,所以我们可以先加载好Prefab,然后Instantiate好后将GameObject传递给UIView,同时传递一个父节点用于挂载。

需要注意的一点是,我们用Activator.CreateInstance实例化UIView子类的时候,父节点ugui的transform的Type为RectTransform,因此我们构造函数的parent类型也要为RectTransform,否则无法正常的实例化对象。

namespace Hotfix.UI
{
    public class GoodsItemView : UIView
    {
        Text m_nameText;
        Button m_buyBtn;

        //因为在Activator.CreateInstance实例化的时候,ugui.transform的Type为RectTransform
        public GoodsItemView(GameObject go, RectTransform parent) : base(go, parent)
        {
        }

        public override void Init()
        {
            base.Init();

            m_buyBtn.onClick.AddListener(OnBuyBtnClicked);
        }

        public override void GetChild()
        {
            base.GetChild();
            m_nameText = transform.Find("NameText").GetComponent<Text>();
            m_buyBtn = transform.Find("BuyButton").GetComponent<Button>();
        }

        public void Setting(string name)
        {
            m_nameText.text = name;
        }

        void OnBuyBtnClicked()
        {
            Debug.Log("m_nameText:"+ m_nameText.text);
        }
    }
}

然后在商城界面MallPanel中实例化对象

namespace Hotfix.UI
{
    [UI("MallPanel")]
    public class MallPanel : UIPanel
    {
        ......

        public override void Init()
        {
            base.Init();
            
            m_closeBtn.onClick.AddListener(OnCloseBtnClick);

            m_mallList.Add("明装");
            m_mallList.Add("燕尔");
            m_mallList.Add("西狩获麟");
            m_mallList.Add("刹那生灭");
            m_mallList.Add("听冰");
            m_mallList.Add("琅嬛");
            m_mallList.Add("陌上花");

            Object itemAsset = Resources.Load("GoodsItem");
            for (int i = 0; i < m_mallList.Count; i++)
            {
                GameObject go = GameObject.Instantiate(itemAsset) as GameObject;
                //m_grid.transform is RectTransform
                GoodsItemView view = UIViewManager.Instance.CreateView<GoodsItemView>(go, m_grid.transform as RectTransform);
                view.Setting(m_mallList[i]);
                view.Show();
            }
        }

        ......
    }
}

第二种情况,我们可以简单的搭建一个界面MessagePanel,里面的内容为三个Toggle,还有三部分内容,我们要实现的就是点击一个Toggle,只显示对应的内容即可。

namespace Hotfix.UI
{
    [UI("MessagePanel")]
    public class MessagePanel : UIPanel
    {
        Button m_closeBtn;

        Toggle m_informationToggle;
        Toggle m_albumToggle;
        Toggle m_journalToggle;

        InformationView m_InformationView;
        AlbumView m_albumView;
        JournalView m_journalView;

        public MessagePanel(string url) : base(url)
        {
        }

        public override void Init()
        {
            base.Init();

            m_informationToggle.onValueChanged.AddListener(OnInformationToggleClicked);
            m_albumToggle.onValueChanged.AddListener(OnAlbumToggleClicked);
            m_journalToggle.onValueChanged.AddListener(OnJournalToggleClicked);

            m_closeBtn.onClick.AddListener(OnCloseBtnClick);
        }

        public override void GetChild()
        {
            base.GetChild();
            m_closeBtn = transform.Find("CloseButton").GetComponent<Button>();

            m_informationToggle = transform.Find("Group/InformationToggle").GetComponent<Toggle>();
            m_albumToggle = transform.Find("Group/AlbumToggle").GetComponent<Toggle>();
            m_journalToggle = transform.Find("Group/JournalToggle").GetComponent<Toggle>();

            m_InformationView = UIViewManager.Instance.CreateView<InformationView>(transform.Find("Content/InformationContent").gameObject);
            m_albumView = UIViewManager.Instance.CreateView<AlbumView>(transform.Find("Content/AlbumContent").gameObject);
            m_journalView = UIViewManager.Instance.CreateView<JournalView>(transform.Find("Content/JournalContent").gameObject);
        }

        public override void Show()
        {
            base.Show();
            m_informationToggle.isOn = true;
        }

        void OnInformationToggleClicked(bool isSelect)
        {
            ShowSelectedView(4);
        }

        void OnAlbumToggleClicked(bool isSelect)
        {
            ShowSelectedView(2);
        }

        void OnJournalToggleClicked(bool isSelect)
        {
            ShowSelectedView(1);
        }

        void ShowSelectedView(int value)
        {
            m_InformationView.SetActive((4 & value) > 0);//100
            m_albumView.SetActive((2 & value) > 0);//010
            m_journalView.SetActive((1 & value) > 0);//001
        }

        void OnCloseBtnClick()
        {
            UIPanelManager.Instance.HidePanel();
        }
    }
}

然后部分内容对应一个UIView,例如InformationView

namespace Hotfix.UI
{
    public class InformationView : UIView
    {
        Text m_nameText;
        Text m_sexText;
        Text m_phoneText;

        public InformationView(GameObject go) : base(go)
        {
        }

        public override void Init()
        {
            base.Init();

            m_nameText.text = "七龙珠";
            m_sexText.text = "成男";
            m_phoneText.text = "158xxxxx094";
        }

        public override void GetChild()
        {
            base.GetChild();
            m_nameText = transform.Find("NameList/ContentText").GetComponent<Text>();
            m_sexText = transform.Find("SexList/ContentText").GetComponent<Text>();
            m_phoneText = transform.Find("PhoneList/ContentText").GetComponent<Text>();
        }
    }
}

这样就能实现一些简单的UI管理,后续功能将继续完善,欢迎大家提出宝贵的意见

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值