com.alicizax.unity.ui.exten.../Runtime/RecyclerView/Layout/LayoutManager.cs
2025-06-03 13:57:23 +08:00

249 lines
6.7 KiB
C#

using System;
using UnityEngine;
namespace AlicizaX.UI.RecyclerView
{
[Serializable]
public abstract class LayoutManager : ILayoutManager
{
protected Vector2 viewportSize;
public Vector2 ViewportSize
{
get => viewportSize;
private set => viewportSize = value;
}
protected Vector2 contentSize;
public Vector2 ContentSize
{
get => contentSize;
private set => contentSize = value;
}
protected Vector2 contentOffset;
public Vector2 ContentOffset
{
get => contentOffset;
private set => contentOffset = value;
}
protected Vector2 viewportOffset;
public Vector2 ViewportOffset
{
get => viewportOffset;
private set => viewportOffset = value;
}
protected IAdapter adapter;
public IAdapter Adapter
{
get => adapter;
set => adapter = value;
}
protected ViewProvider viewProvider;
public ViewProvider ViewProvider
{
get => viewProvider;
set => viewProvider = value;
}
protected RecyclerView recyclerView;
public virtual RecyclerView RecyclerView
{
get => recyclerView;
set => recyclerView = value;
}
protected Direction direction;
public Direction Direction
{
get => direction;
set => direction = value;
}
protected Alignment alignment;
public Alignment Alignment
{
get => alignment;
set => alignment = value;
}
protected Vector2 spacing;
public Vector2 Spacing
{
get => spacing;
set => spacing = value;
}
protected Vector2 padding;
public Vector2 Padding
{
get => padding;
set => padding = value;
}
protected int unit = 1;
public int Unit
{
get => unit;
set => unit = value;
}
protected bool canScroll;
public bool CanScroll
{
get => canScroll;
set => canScroll = value;
}
public float ScrollPosition => recyclerView.GetScrollPosition();
public LayoutManager()
{
}
public void SetContentSize()
{
viewportSize = recyclerView.GetComponent<RectTransform>().rect.size;
contentSize = CalculateContentSize();
contentOffset = CalculateContentOffset();
viewportOffset = CalculateViewportOffset();
}
public void UpdateLayout()
{
foreach (var viewHolder in viewProvider.ViewHolders)
{
Layout(viewHolder, viewHolder.Index);
}
}
public virtual void Layout(ViewHolder viewHolder, int index)
{
Vector2 pos = CalculatePosition(index);
Vector3 position = direction == Direction.Vertical ? new Vector3(pos.x - contentOffset.x, -pos.y + contentOffset.y, 0) : new Vector3(pos.x - contentOffset.x, -pos.y + contentOffset.y, 0);
viewHolder.RectTransform.anchoredPosition3D = position;
}
public abstract Vector2 CalculateContentSize();
public abstract Vector2 CalculatePosition(int index);
public abstract Vector2 CalculateContentOffset();
public abstract Vector2 CalculateViewportOffset();
public abstract int GetStartIndex();
public abstract int GetEndIndex();
public abstract float IndexToPosition(int index);
public abstract int PositionToIndex(float position);
public virtual void DoItemAnimation()
{
}
public virtual bool IsFullVisibleStart(int index)
{
Vector2 vector2 = CalculatePosition(index);
float position = direction == Direction.Vertical ? vector2.y : vector2.x;
return position + GetOffset() >= 0;
}
public virtual bool IsFullInvisibleStart(int index)
{
Vector2 vector2 = CalculatePosition(index + unit);
float position = direction == Direction.Vertical ? vector2.y : vector2.x;
return position + GetOffset() < 0;
}
public virtual bool IsFullVisibleEnd(int index)
{
Vector2 vector2 = CalculatePosition(index + unit);
float position = direction == Direction.Vertical ? vector2.y : vector2.x;
float viewLength = direction == Direction.Vertical ? viewportSize.y : viewportSize.x;
return position + GetOffset() <= viewLength;
}
public virtual bool IsFullInvisibleEnd(int index)
{
Vector2 vector2 = CalculatePosition(index);
float position = direction == Direction.Vertical ? vector2.y : vector2.x;
float viewLength = direction == Direction.Vertical ? viewportSize.y : viewportSize.x;
return position + GetOffset() > viewLength;
}
public virtual bool IsVisible(int index)
{
float position, viewLength;
viewLength = direction == Direction.Vertical ? viewportSize.y : viewportSize.x;
Vector2 vector2 = CalculatePosition(index);
position = direction == Direction.Vertical ? vector2.y : vector2.x;
if (position + GetOffset() > 0 && position + GetOffset() <= viewLength)
{
return true;
}
vector2 = CalculatePosition(index + unit);
position = direction == Direction.Vertical ? vector2.y : vector2.x;
if (position + GetOffset() > 0 && position + GetOffset() <= viewLength)
{
return true;
}
return false;
}
protected virtual float GetFitContentSize()
{
float len;
if (direction == Direction.Vertical)
{
len = alignment == Alignment.Center ? Mathf.Min(contentSize.y, viewportSize.y) : viewportSize.y;
}
else
{
len = alignment == Alignment.Center ? Mathf.Min(contentSize.x, viewportSize.x) : viewportSize.x;
}
return len;
}
protected virtual float GetOffset()
{
return direction == Direction.Vertical ? -contentOffset.y + viewportOffset.y : -contentOffset.x + viewportOffset.x;
}
}
public enum Direction
{
Vertical,
Horizontal,
Custom,
}
public enum Alignment
{
Left,
Center,
Top
}
}