浅谈个人在Unity中的UI管理方案-MVP模式
发布时间:2024年11月26日
目录
一.UI视图管理器的类图设计
1.所有UI视图通过装载继承了ViewDefiner的具体脚本在OnInitialize中绑定与其对应的IViewPresent的具体实现
2.在IViewPresent的具体实现中,依赖一个或多个类作为Model存在
3.在OnInitialize中将他们添加到ViewManager
一切准备就绪后,通过全局单例的ViewManager我们可以在任意地点对UI进行控制,且避免了对UI元素的直接操控。
注意:
1.ViewPresent只负责Model与UI视图的交互,尽量不要在当中写入复杂逻辑
2.Model作为具体的逻辑层存在
3.本方案属于MVP模式,若有想法或不习惯这种形式的可以修改成MVVM或MVC或者其他方案进行尝试
二.具体代码实现
1.ViewManager类
public class ViewManager : Singleton<ViewManager>
{
private readonly Dictionary<string, IViewPresenter> _uiVModelById = new Dictionary<string, IViewPresenter>();
private readonly Dictionary<string, List<IViewPresenter>> _uiVModelByClass = new Dictionary<string, List<IViewPresenter>>();
/// <summary>
/// 添加定义器
/// </summary>
public void AddDefiner<T>(ViewDefiner<T> definer) where T : IViewPresenter, new()
{
if (!string.IsNullOrEmpty(definer.Id))
{
if (_uiVModelById.ContainsKey(definer.Id))
{
GameLogManager.Instance.Error($"添加UIDefiner时错误 ID:[{definer.Id}]已被定义");
return;
}
_uiVModelById.Add(definer.Id, definer.Presenter);
}
if (!string.IsNullOrEmpty(definer.Class))
{
if (!_uiVModelByClass.TryGetValue(definer.Class, out var list))
{
list = new List<IViewPresenter>();
_uiVModelByClass[definer.Class] = list;
}
list.Add(definer.Presenter);
}
}
/// <summary>
/// 移除定义器
/// </summary>
public void RemoveDefiner<T>(ViewDefiner<T> definer) where T : IViewPresenter, new()
{
if (!string.IsNullOrEmpty(definer.Id))
_uiVModelById.Remove(definer.Id);
if (!string.IsNullOrEmpty(definer.Class) && _uiVModelByClass.TryGetValue(definer.Class, out var list))
{
list.Remove(definer.Presenter);
if (list.Count == 0) _uiVModelByClass.Remove(definer.Class);
}
}
/// <summary>
/// 按Id查找
/// </summary>
public T FindById<T>(string id) where T : IViewPresenter
{
return _uiVModelById.TryGetValue(id, out var vm) && vm is T result ?
result : default;
}
/// <summary>
/// 按Class查找UI
/// </summary>
public IEnumerable<T> FindByClass<T>(string className) where T : IViewPresenter
{
if (_uiVModelByClass.TryGetValue(className, out var vms))
{
foreach (var vm in vms)
{
if (vm is T result)
yield return result;
}
}
}
}
2.ViewDefiner类
public abstract class ViewDefiner<T> : MonoBehaviour where T : IViewPresenter, new()
{
public string Id;
public string Class;
public T Presenter;
protected abstract void OnInitialize();
private void Start()
{
Presenter = new T();
Presenter.InitPresenter(gameObject);
ViewManager.Instance.AddDefiner(this);
OnInitialize();
}
private void OnDestroy()
{
ViewManager.Instance.RemoveDefiner(this);
}
}
3.IViewPresenter接口
public interface IViewPresenter
{
void InitPresenter(GameObject view);
}