com.alicizax.unity.ui.exten.../Runtime/RecyclerView/Interaction/ItemInteractionProxy.cs
陈思海 dc8c840d69 RecyclerView 大优化
优化RecycleView 渲染架构
优化RecyclerView 渲染性能 增加 缓存 异步
增加Navagation导航锚点相关
2026-03-31 15:18:50 +08:00

206 lines
5.6 KiB
C#

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace AlicizaX.UI
{
[DisallowMultipleComponent]
public sealed class ItemInteractionProxy : MonoBehaviour,
IPointerClickHandler,
IPointerEnterHandler,
IPointerExitHandler,
ISelectHandler,
IDeselectHandler,
IMoveHandler,
IBeginDragHandler,
IDragHandler,
IEndDragHandler,
ISubmitHandler,
ICancelHandler
{
private IItemInteractionHost host;
private ItemInteractionFlags flags;
private Selectable focusAnchor;
private RecyclerItemSelectable ownedSelectable;
private Scroller parentScroller;
internal void Bind(IItemInteractionHost interactionHost)
{
host = interactionHost;
flags = interactionHost?.InteractionFlags ?? ItemInteractionFlags.None;
parentScroller = GetComponentInParent<Scroller>();
EnsureFocusAnchor();
if (ownedSelectable != null)
{
bool requiresSelection = RequiresSelection(flags);
ownedSelectable.interactable = requiresSelection;
ownedSelectable.enabled = requiresSelection;
}
InvalidateNavigationScope();
}
public void Clear()
{
host = null;
flags = ItemInteractionFlags.None;
parentScroller = null;
if (ownedSelectable != null)
{
ownedSelectable.interactable = false;
ownedSelectable.enabled = false;
}
InvalidateNavigationScope();
}
public Selectable GetSelectable()
{
EnsureFocusAnchor();
return focusAnchor;
}
public void OnPointerClick(PointerEventData eventData)
{
if ((flags & ItemInteractionFlags.PointerClick) != 0)
{
host?.HandlePointerClick(eventData);
}
}
public void OnPointerEnter(PointerEventData eventData)
{
if ((flags & ItemInteractionFlags.PointerEnter) != 0)
{
host?.HandlePointerEnter(eventData);
}
}
public void OnPointerExit(PointerEventData eventData)
{
if ((flags & ItemInteractionFlags.PointerExit) != 0)
{
host?.HandlePointerExit(eventData);
}
}
public void OnSelect(BaseEventData eventData)
{
if ((flags & ItemInteractionFlags.Select) != 0)
{
host?.HandleSelect(eventData);
}
}
public void OnDeselect(BaseEventData eventData)
{
if ((flags & ItemInteractionFlags.Deselect) != 0)
{
host?.HandleDeselect(eventData);
}
}
public void OnMove(AxisEventData eventData)
{
if ((flags & ItemInteractionFlags.Move) != 0)
{
host?.HandleMove(eventData);
}
}
public void OnBeginDrag(PointerEventData eventData)
{
if ((flags & ItemInteractionFlags.BeginDrag) != 0)
{
host?.HandleBeginDrag(eventData);
return;
}
parentScroller?.OnBeginDrag(eventData);
}
public void OnDrag(PointerEventData eventData)
{
if ((flags & ItemInteractionFlags.Drag) != 0)
{
host?.HandleDrag(eventData);
return;
}
parentScroller?.OnDrag(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
if ((flags & ItemInteractionFlags.EndDrag) != 0)
{
host?.HandleEndDrag(eventData);
return;
}
parentScroller?.OnEndDrag(eventData);
}
public void OnSubmit(BaseEventData eventData)
{
if ((flags & ItemInteractionFlags.Submit) != 0)
{
host?.HandleSubmit(eventData);
}
}
public void OnCancel(BaseEventData eventData)
{
if ((flags & ItemInteractionFlags.Cancel) != 0)
{
host?.HandleCancel(eventData);
}
}
private void EnsureFocusAnchor()
{
if (focusAnchor != null)
{
return;
}
focusAnchor = GetComponent<Selectable>();
if (focusAnchor != null)
{
return;
}
ownedSelectable = GetComponent<RecyclerItemSelectable>();
if (ownedSelectable == null)
{
ownedSelectable = gameObject.AddComponent<RecyclerItemSelectable>();
}
focusAnchor = ownedSelectable;
}
private static bool RequiresSelection(ItemInteractionFlags interactionFlags)
{
const ItemInteractionFlags selectionFlags =
ItemInteractionFlags.Select |
ItemInteractionFlags.Deselect |
ItemInteractionFlags.Move |
ItemInteractionFlags.Submit |
ItemInteractionFlags.Cancel;
return (interactionFlags & selectionFlags) != 0;
}
[System.Diagnostics.Conditional("INPUTSYSTEM_SUPPORT")]
private void InvalidateNavigationScope()
{
#if INPUTSYSTEM_SUPPORT && UX_NAVIGATION
var scope = GetComponentInParent<UnityEngine.UI.UXNavigationScope>(true);
scope?.InvalidateSelectableCache();
#endif
}
}
}