在 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管理,後續功能將繼續完善,歡迎大家提出寶貴的意見

發佈了72 篇原創文章 · 獲贊 166 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章