com.alicizax.unity.ui.exten.../Runtime/RecyclerView/ViewHolder/ViewHolder.cs

118 lines
3.2 KiB
C#
Raw Normal View History

using System.Collections.Generic;
2025-03-12 20:59:12 +08:00
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
2025-03-12 20:59:12 +08:00
namespace AlicizaX.UI
2025-03-12 20:59:12 +08:00
{
public abstract partial class ViewHolder : MonoBehaviour
2025-03-12 20:59:12 +08:00
{
private RectTransform rectTransform;
private Selectable focusAnchor;
private readonly List<Selectable> selectableCache = new();
private bool interactionCacheReady;
internal IItemRender CachedItemRender;
internal string CachedItemRenderViewName;
2025-03-28 13:34:33 +08:00
2025-03-12 20:59:12 +08:00
public RectTransform RectTransform
{
get
{
if (rectTransform == null)
{
rectTransform = GetComponent<RectTransform>();
}
2025-03-28 13:34:33 +08:00
2025-03-12 20:59:12 +08:00
return rectTransform;
}
}
2025-05-30 13:43:08 +08:00
public string Name { get; internal set; }
2026-03-11 14:18:07 +08:00
2025-05-30 13:43:08 +08:00
public int Index { get; internal set; }
2025-03-12 20:59:12 +08:00
public int DataIndex { get; internal set; } = -1;
public RecyclerView RecyclerView { get; internal set; }
2025-05-30 13:43:08 +08:00
public uint BindingVersion { get; private set; }
2026-03-30 16:00:20 +08:00
public Vector2 SizeDelta => RectTransform.sizeDelta;
2025-03-12 20:59:12 +08:00
internal uint AdvanceBindingVersion()
{
BindingVersion = BindingVersion == uint.MaxValue ? 1u : BindingVersion + 1u;
return BindingVersion;
}
2026-03-27 14:38:26 +08:00
internal void RefreshInteractionCache()
{
if (interactionCacheReady)
{
return;
}
focusAnchor = GetComponent<Selectable>();
selectableCache.Clear();
GetComponentsInChildren(true, selectableCache);
interactionCacheReady = true;
}
internal bool TryGetFocusTarget(out GameObject target)
{
if (TryGetInteractionFocusTarget(out target))
{
return true;
}
Selectable selectable = IsSelectableFocusable(focusAnchor) ? focusAnchor : null;
if (selectable == null)
{
for (int i = 0; i < selectableCache.Count; i++)
{
if (IsSelectableFocusable(selectableCache[i]))
{
selectable = selectableCache[i];
break;
}
}
}
if (selectable != null)
{
target = selectable.gameObject;
return true;
}
if (ExecuteEvents.CanHandleEvent<IMoveHandler>(gameObject) ||
ExecuteEvents.CanHandleEvent<ISelectHandler>(gameObject) ||
ExecuteEvents.CanHandleEvent<ISubmitHandler>(gameObject))
{
target = gameObject;
return true;
}
target = null;
return false;
}
protected internal virtual void OnRecycled()
2025-03-28 13:34:33 +08:00
{
AdvanceBindingVersion();
Name = string.Empty;
Index = -1;
DataIndex = -1;
RecyclerView = null;
2025-03-28 13:34:33 +08:00
}
2025-04-01 15:21:02 +08:00
private static bool IsSelectableFocusable(Selectable selectable)
2025-04-02 14:53:08 +08:00
{
return selectable != null &&
selectable.IsActive() &&
selectable.IsInteractable();
2025-04-02 14:53:08 +08:00
}
2025-03-12 20:59:12 +08:00
}
}