212 lines
5.7 KiB
C#
212 lines
5.7 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using Assets.Sources.Core.DataBinding;
|
||
using DG.Tweening;
|
||
using UnityEngine;
|
||
|
||
namespace uMVVM.Sources.Infrastructure
|
||
{
|
||
[RequireComponent(typeof(CanvasGroup))]
|
||
public abstract class UnityGuiView<T> : MonoBehaviour, IView<T> where T : ViewModelBase
|
||
{
|
||
private bool _isInitialized;
|
||
public bool destroyOnHide;
|
||
protected readonly PropertyBinder<T> Binder = new PropertyBinder<T>();
|
||
public readonly BindableProperty<T> ViewModelProperty = new BindableProperty<T>();
|
||
|
||
/// <summary>
|
||
/// 显示之后的回掉函数
|
||
/// </summary>
|
||
public Action RevealedAction { get; set; }
|
||
|
||
/// <summary>
|
||
/// 隐藏之后的回掉函数
|
||
/// </summary>
|
||
public Action HiddenAction { get; set; }
|
||
|
||
public T BindingContext
|
||
{
|
||
get { return ViewModelProperty.Value; }
|
||
set
|
||
{
|
||
if (!_isInitialized)
|
||
{
|
||
OnInitialize();
|
||
_isInitialized = true;
|
||
}
|
||
|
||
//触发OnValueChanged事件
|
||
ViewModelProperty.Value = value;
|
||
}
|
||
}
|
||
|
||
public void Reveal(bool immediate = false, Action action = null)
|
||
{
|
||
if (action != null)
|
||
{
|
||
RevealedAction += action;
|
||
}
|
||
|
||
OnAppear();
|
||
OnReveal(immediate);
|
||
OnRevealed();
|
||
}
|
||
|
||
public void Hide(bool immediate = false, Action action = null)
|
||
{
|
||
if (action != null)
|
||
{
|
||
HiddenAction += action;
|
||
}
|
||
|
||
OnHide(immediate);
|
||
OnHidden();
|
||
OnDisappear();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化View,当BindingContext改变时执行
|
||
/// </summary>
|
||
protected virtual void OnInitialize()
|
||
{
|
||
//无所ViewModel的Value怎样变化,只对OnValueChanged事件监听(绑定)一次
|
||
ViewModelProperty.OnValueChanged += OnBindingContextChanged;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 激活gameObject,Disable->Enable
|
||
/// </summary>
|
||
public virtual void OnAppear()
|
||
{
|
||
gameObject.SetActive(true);
|
||
BindingContext.OnStartReveal();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始显示
|
||
/// </summary>
|
||
/// <param name="immediate"></param>
|
||
private void OnReveal(bool immediate)
|
||
{
|
||
if (immediate)
|
||
{
|
||
//立即显示
|
||
transform.localScale = Vector3.one;
|
||
GetComponent<CanvasGroup>().alpha = 1;
|
||
}
|
||
else
|
||
{
|
||
StartAnimatedReveal();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// alpha 0->1 之后执行
|
||
/// </summary>
|
||
public virtual void OnRevealed()
|
||
{
|
||
BindingContext.OnFinishReveal();
|
||
//回掉函数
|
||
if (RevealedAction != null)
|
||
{
|
||
RevealedAction();
|
||
}
|
||
}
|
||
|
||
private void OnHide(bool immediate)
|
||
{
|
||
BindingContext.OnStartHide();
|
||
if (immediate)
|
||
{
|
||
//立即隐藏
|
||
transform.localScale = Vector3.zero;
|
||
GetComponent<CanvasGroup>().alpha = 0;
|
||
}
|
||
else
|
||
{
|
||
StartAnimatedHide();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// alpha 1->0时
|
||
/// </summary>
|
||
public virtual void OnHidden()
|
||
{
|
||
//回掉函数
|
||
if (HiddenAction != null)
|
||
{
|
||
HiddenAction();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 消失 Enable->Disable
|
||
/// </summary>
|
||
public virtual void OnDisappear()
|
||
{
|
||
gameObject.SetActive(false);
|
||
BindingContext.OnFinishHide();
|
||
if (destroyOnHide)
|
||
{
|
||
//销毁
|
||
Destroy(this.gameObject);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 当gameObject将被销毁时,这个方法被调用
|
||
/// </summary>
|
||
public virtual void OnDestroy()
|
||
{
|
||
if (BindingContext == null) return;
|
||
if (BindingContext.IsRevealed)
|
||
{
|
||
Hide(true);
|
||
}
|
||
|
||
BindingContext.OnDestory();
|
||
BindingContext = null;
|
||
ViewModelProperty.OnValueChanged = null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// scale:1,alpha:1
|
||
/// </summary>
|
||
protected virtual void StartAnimatedReveal()
|
||
{
|
||
var canvasGroup = GetComponent<CanvasGroup>();
|
||
canvasGroup.interactable = false;
|
||
transform.localScale = Vector3.one;
|
||
|
||
canvasGroup.DOFade(1, 0.2f).SetDelay(0.2f).OnComplete(() => { canvasGroup.interactable = true; });
|
||
}
|
||
|
||
/// <summary>
|
||
/// alpha:0,scale:0
|
||
/// </summary>
|
||
protected virtual void StartAnimatedHide()
|
||
{
|
||
var canvasGroup = GetComponent<CanvasGroup>();
|
||
canvasGroup.interactable = false;
|
||
canvasGroup.DOFade(0, 0.2f).SetDelay(0.2f).OnComplete(() =>
|
||
{
|
||
transform.localScale = Vector3.zero;
|
||
canvasGroup.interactable = true;
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绑定的上下文发生改变时的响应方法
|
||
/// 利用反射+=/-=OnValuePropertyChanged
|
||
/// </summary>
|
||
public virtual void OnBindingContextChanged(T oldValue, T newValue)
|
||
{
|
||
if (this.ViewModelProperty == null) return;
|
||
Binder.Unbind(oldValue);
|
||
Binder.Bind(newValue);
|
||
}
|
||
}
|
||
} |