上一篇主要處理了一些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管理,後續功能將繼續完善,歡迎大家提出寶貴的意見