249 lines
6.7 KiB
C#
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
|
|
}
|
|
}
|