前言
这里我们所说的不是button.click = myClick 这种方式。而是通过继承点击事件接口,自己重写一个点击事件出来
这个的好处在于方便管理点击事件,方便添加移除点击事件。
思想
UI中一共分为渲染层,点击事件层,资源加载层。
首先我们需要一个点击事件父类,它用于设置,触发指定类型的点击事件
然后就是各事件组件类,继承该父类。其中有包括点击事件,拖拽事件,双击事件等。本案例中只举例点击事件。
接下来就是我们的UI层组件层,它负责点击事件的操作:添加,移除事件监听,触发事件,添加点击事件组件
最后是事件控制器。枚举所有的点击事件类型,枚举所有的点击事件对应的事件组件。根据事件类型枚举查找事件组件等。
代码
- 点击事件基类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class UIEvtCompBase : MonoBehaviour {
/// <summary>
/// 事件UI
/// </summary>
[SerializeField]
protected UIBaseCommpoent eui; //UI的组件,因为组件是要挂载在它的身上的
/// <summary>
/// 设置事件UI
/// </summary>
public void SetEUI(UIBaseCommpoent e)
{
eui = e;
}
/// <summary>
/// 触发事件
/// </summary>
/// <param name="evtType"></param>
/// <param name="evtData"></param>
protected void TriggerUiEvt(UiEvtEnum evtType, BaseEventData evtData)
{
if (eui == null)
{
eui = GetComponent<UIBaseCommpoent>();
if (eui == null)
return;
}
eui.DispatchEvent(evtType, evtData);
}
}
- 事件组件类
using System;
using UnityEngine.EventSystems;
/// <summary>
/// 普通点击事件组件
/// </summary>
public class CommonEvtComp : UIEvtCompBase, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
/// <summary>
/// 点击事件
/// </summary>
/// <param name="eventData">事件数据</param>
public virtual void OnPointerClick(PointerEventData eventData)
{
TriggerUiEvt(UiEvtEnum.Click, eventData);
}
/// <summary>
/// 鼠标移入
/// </summary>
/// <param name="eventData">事件数据</param>
public virtual void OnPointerEnter(PointerEventData eventData)
{
TriggerUiEvt(UiEvtEnum.MouseIn, eventData);
}
/// <summary>
/// 鼠标移出
/// </summary>
/// <param name="eventData">事件数据</param>
public virtual void OnPointerExit(PointerEventData eventData)
{
TriggerUiEvt(UiEvtEnum.MouseOut, eventData);
}
/// <summary>
/// 按下
/// </summary>
/// <param name="eventData"></param>
public void OnPointerDown(PointerEventData eventData)
{
TriggerUiEvt(UiEvtEnum.PointerDown, eventData);
}
/// <summary>
/// 弹起
/// </summary>
/// <param name="eventData"></param>
public void OnPointerUp(PointerEventData eventData)
{
TriggerUiEvt(UiEvtEnum.PointerUp, eventData);
}
}
- UI事件数据类
public class UIEvtData
{
public TouchCallback touchCallback; //这个是点击事件的回调函数,在事件控制器中有具体的写法
public System.Object param; //点击事件监听时传的参数
public UIEvtData(TouchCallback touchCallback,System.Object param)
{
this.touchCallback = touchCallback;
this.param = param;
}
public void CallBack()
{
touchCallback(param);
}
}
- UI组件类
/// <summary>
/// UI点击事件层
/// </summary>
public class UIBaseCommpoent : MonoBehaviour
{
/// <summary>
/// 监听的事件字典
/// </summary>
protected Dictionary<UiEvtEnum, List<UIEvtData>> uiEvtDic;
/// <summary>
/// 事件组件类型-组件
/// </summary>
protected Dictionary<Type, UIEvtCompBase> uiEvtCompDic;
//1,
/// <summary>
/// 触发点击事件
/// </summary>
/// <param name="evtType"></param>
/// <param name="evtData"></param>
public void DispatchEvent(UiEvtEnum evtType, BaseEventData evtData)
{
List<UIEvtData> list = null;
if(uiEvtDic == null)
{
uiEvtDic = new Dictionary<UiEvtEnum, List<UIEvtData>>();
}
if(uiEvtDic.TryGetValue(evtType,out list))
{
foreach (UIEvtData eventItem in list)
{
eventItem.CallBack();
}
}
}
/// <summary>
/// 添加监听事件
/// </summary>
/// <param name="evtType">事件类型枚举</param>
/// <param name="func">回调函数</param>
/// <param name="attachParam">附加参数</param>
public virtual void AddEventListener(UiEvtEnum evtType, TouchCallback func, System.Object attachParam = null)
{
List<UIEvtData> list = null;
if (uiEvtDic == null)
{
uiEvtDic = new Dictionary<UiEvtEnum, List<UIEvtData>>();
}
Type t = UIEventCtrl.GetCompByEvt(evtType);
if (t != null)
{
if (uiEvtCompDic == null)
uiEvtCompDic = new Dictionary<Type, UIEvtCompBase>();
UIEvtCompBase comp = null;
uiEvtCompDic.TryGetValue(t, out comp);
if(comp == null)
{
comp = gameObject.AddComponent(t) as UIEvtCompBase; //添加点击事件
uiEvtCompDic.Add(t, comp); //点击事件添加到字典中,不会重复添加
}
}
uiEvtDic.TryGetValue(evtType, out list); //一个按钮会有多个事件监听,所以用list存储
if (list == null)
{
list = new List<UIEvtData>();
uiEvtDic.Add(evtType, list);
}
list.Add(new UIEvtData(func, attachParam));
}
/// <summary>
/// 移除监听事件
/// </summary>
/// <param name="evtType">事件类型枚举</param>
/// <param name="func">回调函数</param>
/// <param name="attachParam">附加参数</param>
public virtual void RemoveEventListener(UiEvtEnum evtType, TouchCallback func, System.Object attachParam = null)
{
List<UIEvtData> list = null;
if (uiEvtDic.TryGetValue(evtType, out list))
{
for(int i = 0; i < list.Count; i++)
{
if (func == list[i].touchCallback)
{
list.RemoveAt(i);
break;
}
}
}
}
}
using System;
/// <summary>
/// 事件类型枚举
/// </summary>
public enum UiEvtEnum
{
None = 0,
/// <summary>
/// 点击事件
/// </summary>
Click,
/// <summary>
/// 鼠标移入事件
/// </summary>
MouseIn,
/// <summary>
/// 鼠标移出事件
/// </summary>
MouseOut,
/// <summary>
/// 按下
/// </summary>
PointerDown,
/// <summary>
/// 弹起
/// </summary>
PointerUp,
/// <summary>
/// 列表(MList)节点数量改变事件
/// </summary>
ItemNumChange,
/// <summary>
/// 列表(MList)节点索引改变事件
/// </summary>
ItemIndexChange,
/// <summary>
/// 列表(MList)节点点击事件
/// </summary>
ItemClick,
/// <summary>
/// 数据改变事件
/// </summary>
ValueChange,
/// <summary>
/// 链接点击事件
/// </summary>
link,
/// <summary>
/// 结束事件
/// </summary>
complete,
/// <summary>
/// 开始拖拽
/// </summary>
BeginDrag,
/// <summary>
/// 拖拽
/// </summary>
Drag,
/// <summary>
/// 结束拖拽
/// </summary>
EndDrag,
/// <summary>
/// 接收到来自其他控件的拖拽
/// </summary>
ReceiveDragFrom,
/// <summary>
/// 状态改变
/// </summary>
StateChange,
/// <summary>
/// 长按
/// </summary>
LongPress,
/// <summary>
/// 获得焦点
/// </summary>
GetFocused,
/// <summary>
/// 失去焦点
/// </summary>
LossFocused
}
/// <summary>
/// 点击事件回调
/// </summary>
/// <param name="value">响应所传的参数表</param>
/// <param name="attachParam"></param>
public delegate void TouchCallback(object attachParam);
public class UIEventCtrl {
/// <summary>
/// 事件类型-脚本
/// </summary>
public static Type[] uiEvtTypes = new Type[] {
null
, typeof(CommonEvtComp)
, typeof(CommonEvtComp)
, typeof(CommonEvtComp)
, typeof(CommonEvtComp)
, typeof(CommonEvtComp)
, null
, null
, null
, null
, null
, null
, typeof(DragEvtComp)
, typeof(DragEvtComp)
, typeof(DragEvtComp)
, null
, null
};
/// <summary>
/// UI事件管理
/// </summary>
public UIEventCtrl()
{ }
/// <summary>
/// 根据事件类型获得对应的脚本类型
/// </summary>
/// <param name="evtType">事件类型</param>
/// <returns>脚本类型</returns>
public static Type GetCompByEvt(UiEvtEnum evtType)
{
return uiEvtTypes[(int)evtType];
}
}
使用
mImage.AddEventListener(UiEvtEnum.Click, Touch, "初始数据");
mImage.RemoveEventListener(UiEvtEnum.Drag, Touch);