修改
This commit is contained in:
parent
fc993a1dbe
commit
26c205ddc0
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@ GameObject:
|
|||||||
- component: {fileID: 409256563818501030}
|
- component: {fileID: 409256563818501030}
|
||||||
- component: {fileID: 4967247000384896254}
|
- component: {fileID: 4967247000384896254}
|
||||||
- component: {fileID: 2527097672867102998}
|
- component: {fileID: 2527097672867102998}
|
||||||
- component: {fileID: 144409482669617178}
|
- component: {fileID: 222070472718835377}
|
||||||
m_Layer: 5
|
m_Layer: 5
|
||||||
m_Name: ScrollView
|
m_Name: ScrollView
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@ -90,9 +90,8 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 7efd8e83d2092b347952108134dc37eb, type: 3}
|
m_Script: {fileID: 11500000, guid: 7efd8e83d2092b347952108134dc37eb, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
direction: 1
|
direction: 0
|
||||||
alignment: 1
|
alignment: 1
|
||||||
content: {fileID: 7227160576944475251}
|
|
||||||
spacing: {x: 0, y: 0}
|
spacing: {x: 0, y: 0}
|
||||||
padding: {x: 0, y: 0}
|
padding: {x: 0, y: 0}
|
||||||
scroll: 1
|
scroll: 1
|
||||||
@ -100,20 +99,21 @@ MonoBehaviour:
|
|||||||
scrollSpeed: 10
|
scrollSpeed: 10
|
||||||
wheelSpeed: 30
|
wheelSpeed: 30
|
||||||
templates: []
|
templates: []
|
||||||
_scrollerTypeName: AlicizaX.UI.RecyclerView.Scroller
|
content: {fileID: 7227160576944475251}
|
||||||
_scroller: {fileID: 144409482669617178}
|
showScrollBar: 0
|
||||||
_showScrollBar: 0
|
scrollbar: {fileID: 0}
|
||||||
_scrollbar: {fileID: 0}
|
|
||||||
_layoutManagerTypeName: AlicizaX.UI.LinearLayoutManager
|
_layoutManagerTypeName: AlicizaX.UI.LinearLayoutManager
|
||||||
_layoutManager:
|
layoutManager:
|
||||||
rid: 7492395943315111994
|
rid: 6739296571988901898
|
||||||
|
_scrollerTypeName: AlicizaX.UI.Scroller
|
||||||
|
scroller: {fileID: 222070472718835377}
|
||||||
references:
|
references:
|
||||||
version: 2
|
version: 2
|
||||||
RefIds:
|
RefIds:
|
||||||
- rid: 7492395943315111994
|
- rid: 6739296571988901898
|
||||||
type: {class: LinearLayoutManager, ns: AlicizaX.UI, asm: AlicizaX.UI.Extension}
|
type: {class: LinearLayoutManager, ns: AlicizaX.UI, asm: AlicizaX.UI.Extension}
|
||||||
data:
|
data:
|
||||||
--- !u!114 &144409482669617178
|
--- !u!114 &222070472718835377
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
@ -125,6 +125,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 7b7de4cb3a1546e4a9ade6b8dbf8af92, type: 3}
|
m_Script: {fileID: 11500000, guid: 7b7de4cb3a1546e4a9ade6b8dbf8af92, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
dragStopTime: 0
|
||||||
--- !u!1 &9220717789715235424
|
--- !u!1 &9220717789715235424
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@ -69,7 +69,7 @@ namespace AlicizaX.UI
|
|||||||
recyclerView.Refresh();
|
recyclerView.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected internal virtual void SetList(List<T> list)
|
public virtual void SetList(List<T> list)
|
||||||
{
|
{
|
||||||
this.list = list;
|
this.list = list;
|
||||||
recyclerView.Reset();
|
recyclerView.Reset();
|
||||||
|
|||||||
@ -87,7 +87,7 @@ namespace AlicizaX.UI
|
|||||||
base.NotifyDataChanged();
|
base.NotifyDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected internal override void SetList(List<TData> list)
|
public override void SetList(List<TData> list)
|
||||||
{
|
{
|
||||||
showList.Clear();
|
showList.Clear();
|
||||||
base.SetList(list);
|
base.SetList(list);
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 05736c35a54b467a966b416c1461ba61
|
guid: d43a3e6aece04b86ab8eb139abb89e46
|
||||||
timeCreated: 1763617414
|
timeCreated: 1766661642
|
||||||
@ -1,3 +1,3 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: a059b7119e284e37a88a569f76b40579
|
guid: cacaed2312884ce9ba739399b8271b93
|
||||||
timeCreated: 1763617420
|
timeCreated: 1766661647
|
||||||
@ -1,3 +1,3 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: d42e2db77425447490cb9f68003e818b
|
guid: fdf59811e23f47f19be6398684473df2
|
||||||
timeCreated: 1741771999
|
timeCreated: 1766647995
|
||||||
@ -1,48 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
|
||||||
{
|
|
||||||
[Serializable]
|
|
||||||
public class AlignableLinearLayoutManager : LinearLayoutManager
|
|
||||||
{
|
|
||||||
[SerializeField] private float alignmentCount = 0f; // 对齐比例 (0=顶部, 1=底部, 0.5=居中)
|
|
||||||
|
|
||||||
public override Vector2 CalculatePosition(int index)
|
|
||||||
{
|
|
||||||
float position;
|
|
||||||
|
|
||||||
if (direction == Direction.Vertical)
|
|
||||||
{
|
|
||||||
position = index * (lineHeight + spacing.y) - ScrollPosition ;
|
|
||||||
return new Vector2(0, position + padding.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
position = index * (lineHeight + spacing.x) - ScrollPosition ;
|
|
||||||
var a = new Vector2(position + padding.x, 0);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override float IndexToPosition(int index)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= adapter.GetItemCount()) return 0;
|
|
||||||
|
|
||||||
float len, viewLength, position;
|
|
||||||
|
|
||||||
if (direction == Direction.Vertical)
|
|
||||||
{
|
|
||||||
len = index * (lineHeight + spacing.y) - ((lineHeight + spacing.y) * alignmentCount);
|
|
||||||
viewLength = viewportSize.y;
|
|
||||||
position = len + viewLength > contentSize.y ? contentSize.y - viewportSize.y : len;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
len = index * (lineHeight + spacing.x);
|
|
||||||
viewLength = viewportSize.x;
|
|
||||||
position = len + viewLength > contentSize.x ? contentSize.x - viewportSize.x : len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e5cb3f76e0f84a7aa75959e194f524b5
|
|
||||||
timeCreated: 1748588163
|
|
||||||
@ -3,23 +3,20 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
|
[System.Serializable]
|
||||||
public class CircleLayoutManager : LayoutManager
|
public class CircleLayoutManager : LayoutManager
|
||||||
{
|
{
|
||||||
private float radius;
|
|
||||||
private float intervalAngle;
|
|
||||||
|
|
||||||
private new CircleDirection direction;
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
|
private CircleDirection circleDirection= CircleDirection.Positive;
|
||||||
|
[SerializeField]
|
||||||
|
private float intervalAngle=0;
|
||||||
|
|
||||||
|
private float radius;
|
||||||
private float initalAngle;
|
private float initalAngle;
|
||||||
|
|
||||||
|
|
||||||
public CircleLayoutManager(CircleDirection direction = CircleDirection.Positive)
|
|
||||||
{
|
|
||||||
this.direction = direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CircleLayoutManager()
|
public CircleLayoutManager()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Vector2 CalculateContentSize()
|
public override Vector2 CalculateContentSize()
|
||||||
@ -49,7 +46,7 @@ namespace AlicizaX.UI
|
|||||||
public override Vector2 CalculatePosition(int index)
|
public override Vector2 CalculatePosition(int index)
|
||||||
{
|
{
|
||||||
float angle = index * intervalAngle;
|
float angle = index * intervalAngle;
|
||||||
angle = direction == CircleDirection.Positive ? angle : -angle;
|
angle = circleDirection == CircleDirection.Positive ? angle : -angle;
|
||||||
angle += initalAngle + ScrollPosition;
|
angle += initalAngle + ScrollPosition;
|
||||||
float radian = angle * (Mathf.PI / 180f);
|
float radian = angle * (Mathf.PI / 180f);
|
||||||
float x = radius * Mathf.Sin(radian);
|
float x = radius * Mathf.Sin(radian);
|
||||||
@ -97,7 +94,7 @@ namespace AlicizaX.UI
|
|||||||
for (int i = 0; i < viewHolders.Count; i++)
|
for (int i = 0; i < viewHolders.Count; i++)
|
||||||
{
|
{
|
||||||
float angle = i * intervalAngle + initalAngle;
|
float angle = i * intervalAngle + initalAngle;
|
||||||
angle = direction == CircleDirection.Positive ? angle + ScrollPosition : angle - ScrollPosition;
|
angle = circleDirection == CircleDirection.Positive ? angle + ScrollPosition : angle - ScrollPosition;
|
||||||
float delta = (angle - initalAngle) % 360;
|
float delta = (angle - initalAngle) % 360;
|
||||||
delta = delta < 0 ? delta + 360 : delta;
|
delta = delta < 0 ? delta + 360 : delta;
|
||||||
delta = delta > 180 ? 360 - delta : delta;
|
delta = delta > 180 ? 360 - delta : delta;
|
||||||
|
|||||||
@ -1,18 +1,17 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
[Serializable]
|
[System.Serializable]
|
||||||
public class GridLayoutManager : LayoutManager
|
public class GridLayoutManager : LayoutManager
|
||||||
{
|
{
|
||||||
private Vector2 cellSize;
|
private Vector2 cellSize;
|
||||||
|
|
||||||
[SerializeField] private int cellCount;
|
[SerializeField] private int cellCounnt = 1;
|
||||||
|
|
||||||
public GridLayoutManager()
|
public GridLayoutManager()
|
||||||
{
|
{
|
||||||
unit = cellCount;
|
this.unit = cellCounnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Vector2 CalculateContentSize()
|
public override Vector2 CalculateContentSize()
|
||||||
@ -63,7 +62,6 @@ namespace AlicizaX.UI
|
|||||||
width = viewportSize.x;
|
width = viewportSize.x;
|
||||||
height = viewportSize.y;
|
height = viewportSize.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Vector2((width - cellSize.x) / 2, (height - cellSize.y) / 2);
|
return new Vector2((width - cellSize.x) / 2, (height - cellSize.y) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +78,6 @@ namespace AlicizaX.UI
|
|||||||
width = viewportSize.x;
|
width = viewportSize.x;
|
||||||
height = viewportSize.y;
|
height = viewportSize.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Vector2((width - cellSize.x) / 2, (height - cellSize.y) / 2);
|
return new Vector2((width - cellSize.x) / 2, (height - cellSize.y) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
[Serializable]
|
[System.Serializable]
|
||||||
public abstract class LayoutManager : ILayoutManager
|
public abstract class LayoutManager : ILayoutManager
|
||||||
{
|
{
|
||||||
protected Vector2 viewportSize;
|
protected Vector2 viewportSize;
|
||||||
|
|
||||||
public Vector2 ViewportSize
|
public Vector2 ViewportSize
|
||||||
{
|
{
|
||||||
get => viewportSize;
|
get => viewportSize;
|
||||||
@ -15,7 +13,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Vector2 contentSize;
|
protected Vector2 contentSize;
|
||||||
|
|
||||||
public Vector2 ContentSize
|
public Vector2 ContentSize
|
||||||
{
|
{
|
||||||
get => contentSize;
|
get => contentSize;
|
||||||
@ -23,7 +20,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Vector2 contentOffset;
|
protected Vector2 contentOffset;
|
||||||
|
|
||||||
public Vector2 ContentOffset
|
public Vector2 ContentOffset
|
||||||
{
|
{
|
||||||
get => contentOffset;
|
get => contentOffset;
|
||||||
@ -31,7 +27,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Vector2 viewportOffset;
|
protected Vector2 viewportOffset;
|
||||||
|
|
||||||
public Vector2 ViewportOffset
|
public Vector2 ViewportOffset
|
||||||
{
|
{
|
||||||
get => viewportOffset;
|
get => viewportOffset;
|
||||||
@ -39,7 +34,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected IAdapter adapter;
|
protected IAdapter adapter;
|
||||||
|
|
||||||
public IAdapter Adapter
|
public IAdapter Adapter
|
||||||
{
|
{
|
||||||
get => adapter;
|
get => adapter;
|
||||||
@ -47,7 +41,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected ViewProvider viewProvider;
|
protected ViewProvider viewProvider;
|
||||||
|
|
||||||
public ViewProvider ViewProvider
|
public ViewProvider ViewProvider
|
||||||
{
|
{
|
||||||
get => viewProvider;
|
get => viewProvider;
|
||||||
@ -55,7 +48,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected RecyclerView recyclerView;
|
protected RecyclerView recyclerView;
|
||||||
|
|
||||||
public virtual RecyclerView RecyclerView
|
public virtual RecyclerView RecyclerView
|
||||||
{
|
{
|
||||||
get => recyclerView;
|
get => recyclerView;
|
||||||
@ -63,7 +55,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Direction direction;
|
protected Direction direction;
|
||||||
|
|
||||||
public Direction Direction
|
public Direction Direction
|
||||||
{
|
{
|
||||||
get => direction;
|
get => direction;
|
||||||
@ -71,7 +62,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Alignment alignment;
|
protected Alignment alignment;
|
||||||
|
|
||||||
public Alignment Alignment
|
public Alignment Alignment
|
||||||
{
|
{
|
||||||
get => alignment;
|
get => alignment;
|
||||||
@ -79,7 +69,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Vector2 spacing;
|
protected Vector2 spacing;
|
||||||
|
|
||||||
public Vector2 Spacing
|
public Vector2 Spacing
|
||||||
{
|
{
|
||||||
get => spacing;
|
get => spacing;
|
||||||
@ -87,7 +76,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Vector2 padding;
|
protected Vector2 padding;
|
||||||
|
|
||||||
public Vector2 Padding
|
public Vector2 Padding
|
||||||
{
|
{
|
||||||
get => padding;
|
get => padding;
|
||||||
@ -95,26 +83,16 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected int unit = 1;
|
protected int unit = 1;
|
||||||
|
|
||||||
public int Unit
|
public int Unit
|
||||||
{
|
{
|
||||||
get => unit;
|
get => unit;
|
||||||
set => unit = value;
|
set => unit = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool canScroll;
|
|
||||||
|
|
||||||
public bool CanScroll
|
|
||||||
{
|
|
||||||
get => canScroll;
|
|
||||||
set => canScroll = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float ScrollPosition => recyclerView.GetScrollPosition();
|
public float ScrollPosition => recyclerView.GetScrollPosition();
|
||||||
|
|
||||||
public LayoutManager()
|
public LayoutManager() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetContentSize()
|
public void SetContentSize()
|
||||||
{
|
{
|
||||||
@ -135,7 +113,9 @@ namespace AlicizaX.UI
|
|||||||
public virtual void Layout(ViewHolder viewHolder, int index)
|
public virtual void Layout(ViewHolder viewHolder, int index)
|
||||||
{
|
{
|
||||||
Vector2 pos = CalculatePosition(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);
|
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;
|
viewHolder.RectTransform.anchoredPosition3D = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,9 +135,7 @@ namespace AlicizaX.UI
|
|||||||
|
|
||||||
public abstract int PositionToIndex(float position);
|
public abstract int PositionToIndex(float position);
|
||||||
|
|
||||||
public virtual void DoItemAnimation()
|
public virtual void DoItemAnimation() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool IsFullVisibleStart(int index)
|
public virtual bool IsFullVisibleStart(int index)
|
||||||
{
|
{
|
||||||
@ -222,7 +200,6 @@ namespace AlicizaX.UI
|
|||||||
{
|
{
|
||||||
len = alignment == Alignment.Center ? Mathf.Min(contentSize.x, viewportSize.x) : viewportSize.x;
|
len = alignment == Alignment.Center ? Mathf.Min(contentSize.x, viewportSize.x) : viewportSize.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,9 +211,9 @@ namespace AlicizaX.UI
|
|||||||
|
|
||||||
public enum Direction
|
public enum Direction
|
||||||
{
|
{
|
||||||
Vertical,
|
Vertical = 0,
|
||||||
Horizontal,
|
Horizontal = 1,
|
||||||
Custom,
|
Custom = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Alignment
|
public enum Alignment
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
|
[Serializable]
|
||||||
public class LinearLayoutManager : LayoutManager
|
public class LinearLayoutManager : LayoutManager
|
||||||
{
|
{
|
||||||
protected float lineHeight;
|
protected float lineHeight;
|
||||||
|
|
||||||
public LinearLayoutManager()
|
public LinearLayoutManager() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Vector2 CalculateContentSize()
|
public override Vector2 CalculateContentSize()
|
||||||
{
|
{
|
||||||
@ -22,7 +22,6 @@ namespace AlicizaX.UI
|
|||||||
position = index * (lineHeight + spacing.y) - spacing.y;
|
position = index * (lineHeight + spacing.y) - spacing.y;
|
||||||
return new Vector2(contentSize.x, position + padding.y * 2);
|
return new Vector2(contentSize.x, position + padding.y * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
position = index * (lineHeight + spacing.x) - spacing.x;
|
position = index * (lineHeight + spacing.x) - spacing.x;
|
||||||
return new Vector2(position + padding.x * 2, contentSize.y);
|
return new Vector2(position + padding.x * 2, contentSize.y);
|
||||||
}
|
}
|
||||||
@ -35,7 +34,6 @@ namespace AlicizaX.UI
|
|||||||
position = index * (lineHeight + spacing.y) - ScrollPosition;
|
position = index * (lineHeight + spacing.y) - ScrollPosition;
|
||||||
return new Vector2(0, position + padding.y);
|
return new Vector2(0, position + padding.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
position = index * (lineHeight + spacing.x) - ScrollPosition;
|
position = index * (lineHeight + spacing.x) - ScrollPosition;
|
||||||
return new Vector2(position + padding.x, 0);
|
return new Vector2(position + padding.x, 0);
|
||||||
}
|
}
|
||||||
@ -47,7 +45,6 @@ namespace AlicizaX.UI
|
|||||||
{
|
{
|
||||||
return new Vector2(0, (len - lineHeight) / 2);
|
return new Vector2(0, (len - lineHeight) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Vector2((len - lineHeight) / 2, 0);
|
return new Vector2((len - lineHeight) / 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +54,6 @@ namespace AlicizaX.UI
|
|||||||
{
|
{
|
||||||
return new Vector2(0, (viewportSize.y - lineHeight) / 2);
|
return new Vector2(0, (viewportSize.y - lineHeight) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Vector2((viewportSize.x - lineHeight) / 2, 0);
|
return new Vector2((viewportSize.x - lineHeight) / 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
|
[Serializable]
|
||||||
public class MixedLayoutManager : LayoutManager
|
public class MixedLayoutManager : LayoutManager
|
||||||
{
|
{
|
||||||
public MixedLayoutManager() { }
|
public MixedLayoutManager() { }
|
||||||
|
|||||||
@ -4,10 +4,10 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
|
[Serializable]
|
||||||
public class PageLayoutManager : LinearLayoutManager
|
public class PageLayoutManager : LinearLayoutManager
|
||||||
{
|
{
|
||||||
[SerializeField]
|
[SerializeField] private float minScale = 0.9f;
|
||||||
private float minScale;
|
|
||||||
|
|
||||||
public PageLayoutManager()
|
public PageLayoutManager()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 3a9bb27da68d4451a7d79cdb7abc1506
|
guid: 3a9bb27da68d4451a7d79cdb7abc1506
|
||||||
timeCreated: 1748431180
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
|
public interface IMixedObjectFactory<T> where T : class
|
||||||
|
|
||||||
internal interface IMixedObjectFactory<T> where T : class
|
|
||||||
{
|
{
|
||||||
T Create(string typeName);
|
T Create(string typeName);
|
||||||
|
|
||||||
@ -12,5 +10,4 @@ namespace SimpleObjectPool
|
|||||||
|
|
||||||
bool Validate(string typeName, T obj);
|
bool Validate(string typeName, T obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
internal interface IMixedObjectPool<T> : IDisposable where T : class
|
public interface IMixedObjectPool<T> : IDisposable where T : class
|
||||||
{
|
{
|
||||||
T Allocate(string typeName);
|
T Allocate(string typeName);
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
|
public interface IObjectFactory<T> where T : class
|
||||||
|
|
||||||
internal interface IObjectFactory<T> where T : class
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建对象
|
/// 创建对象
|
||||||
@ -29,5 +27,4 @@ namespace SimpleObjectPool
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool Validate(T obj);
|
bool Validate(T obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
internal interface IObjectPool : IDisposable
|
public interface IObjectPool : IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从池子中分配一个可用对象,没有的话就创建一个
|
/// 从池子中分配一个可用对象,没有的话就创建一个
|
||||||
@ -17,7 +17,7 @@ namespace SimpleObjectPool
|
|||||||
void Free(object obj);
|
void Free(object obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal interface IObjectPool<T> : IObjectPool, IDisposable where T : class
|
public interface IObjectPool<T> : IObjectPool, IDisposable where T : class
|
||||||
{
|
{
|
||||||
new T Allocate();
|
new T Allocate();
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
|
public interface IPooledObject
|
||||||
|
|
||||||
internal interface IPooledObject
|
|
||||||
{
|
{
|
||||||
void Free();
|
void Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
internal class MixedObjectPool<T> : IMixedObjectPool<T> where T : class
|
public class MixedObjectPool<T> : IMixedObjectPool<T> where T : class
|
||||||
{
|
{
|
||||||
private const int DEFAULT_MAX_SIZE_PER_TYPE = 10;
|
private const int DEFAULT_MAX_SIZE_PER_TYPE = 10;
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
internal class ObjectPool<T> : IObjectPool<T> where T : class
|
public class ObjectPool<T> : IObjectPool<T> where T : class
|
||||||
{
|
{
|
||||||
private int maxSize;
|
private int maxSize;
|
||||||
private int initialSize;
|
private int initialSize;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
internal class UnityComponentFactory<T> : IObjectFactory<T> where T : Component
|
public class UnityComponentFactory<T> : IObjectFactory<T> where T : Component
|
||||||
{
|
{
|
||||||
private T template;
|
private T template;
|
||||||
private Transform parent;
|
private Transform parent;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
internal class UnityGameObjectFactory : IObjectFactory<GameObject>
|
public class UnityGameObjectFactory : IObjectFactory<GameObject>
|
||||||
{
|
{
|
||||||
protected GameObject template;
|
protected GameObject template;
|
||||||
protected Transform parent;
|
protected Transform parent;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
internal class UnityMixedComponentFactory<T> : IMixedObjectFactory<T> where T : Component
|
public class UnityMixedComponentFactory<T> : IMixedObjectFactory<T> where T : Component
|
||||||
{
|
{
|
||||||
protected T template;
|
protected T template;
|
||||||
protected Transform parent;
|
protected Transform parent;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
namespace SimpleObjectPool
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
internal class UnityMixedGameObjectFactory : IMixedObjectFactory<GameObject>
|
public class UnityMixedGameObjectFactory : IMixedObjectFactory<GameObject>
|
||||||
{
|
{
|
||||||
protected GameObject template;
|
protected GameObject template;
|
||||||
protected Transform parent;
|
protected Transform parent;
|
||||||
@ -40,5 +40,4 @@ namespace SimpleObjectPool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,61 @@
|
|||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Serialization;
|
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
public class RecyclerView : MonoBehaviour
|
public class RecyclerView : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private Direction direction;
|
#region Serialized Fields - Layout Settings
|
||||||
|
|
||||||
|
[HideInInspector] [SerializeField] private Direction direction;
|
||||||
|
[HideInInspector] [SerializeField] private Alignment alignment;
|
||||||
|
[HideInInspector] [SerializeField] private Vector2 spacing;
|
||||||
|
[HideInInspector] [SerializeField] private Vector2 padding;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serialized Fields - Scroll Settings
|
||||||
|
|
||||||
|
[HideInInspector] [SerializeField] private bool scroll;
|
||||||
|
[HideInInspector] [SerializeField] private bool snap;
|
||||||
|
|
||||||
|
[HideInInspector] [SerializeField, Range(1f, 50f)]
|
||||||
|
private float scrollSpeed = 7f;
|
||||||
|
|
||||||
|
[HideInInspector] [SerializeField, Range(10f, 50f)]
|
||||||
|
private float wheelSpeed = 30f;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serialized Fields - Components
|
||||||
|
|
||||||
|
[HideInInspector] [SerializeField] private ViewHolder[] templates;
|
||||||
|
[HideInInspector] [SerializeField] private RectTransform content;
|
||||||
|
[HideInInspector] [SerializeField] private bool showScrollBar;
|
||||||
|
[HideInInspector] [SerializeField] private Scrollbar scrollbar;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serialized Fields - Internal (Hidden in Inspector)
|
||||||
|
|
||||||
|
[HideInInspector] [SerializeField] private string _layoutManagerTypeName;
|
||||||
|
[SerializeReference] private LayoutManager layoutManager;
|
||||||
|
[HideInInspector] [SerializeField] private string _scrollerTypeName;
|
||||||
|
[HideInInspector] [SerializeReference] private Scroller scroller;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Fields
|
||||||
|
|
||||||
|
private ViewProvider viewProvider;
|
||||||
|
private int startIndex;
|
||||||
|
private int endIndex;
|
||||||
|
private int currentIndex;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Properties - Layout Settings
|
||||||
|
|
||||||
public Direction Direction
|
public Direction Direction
|
||||||
{
|
{
|
||||||
@ -15,15 +63,119 @@ namespace AlicizaX.UI
|
|||||||
set => direction = value;
|
set => direction = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField] private Alignment alignment;
|
|
||||||
|
|
||||||
public Alignment Alignment
|
public Alignment Alignment
|
||||||
{
|
{
|
||||||
get => alignment;
|
get => alignment;
|
||||||
set => alignment = value;
|
set => alignment = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField] private RectTransform content;
|
public Vector2 Spacing
|
||||||
|
{
|
||||||
|
get => spacing;
|
||||||
|
set => spacing = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 Padding
|
||||||
|
{
|
||||||
|
get => padding;
|
||||||
|
set => padding = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Properties - Scroll Settings
|
||||||
|
|
||||||
|
public bool Scroll
|
||||||
|
{
|
||||||
|
get => scroll;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (scroll == value) return;
|
||||||
|
scroll = value;
|
||||||
|
|
||||||
|
// 启/停 scroller(如果存在)
|
||||||
|
if (scroller != null)
|
||||||
|
{
|
||||||
|
// 如果 Scroller 是 MonoBehaviour,可以启/停组件;否则回退到设置一个 Position/flags
|
||||||
|
scroller.enabled = scroll;
|
||||||
|
|
||||||
|
// 将当前的滚动相关配置下发到 scroller,保持一致性
|
||||||
|
scroller.ScrollSpeed = scrollSpeed;
|
||||||
|
scroller.WheelSpeed = wheelSpeed;
|
||||||
|
scroller.Snap = snap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新 scrollbar 显示(只有在 showScrollBar 为 true 时才显示)
|
||||||
|
if (scrollbar != null)
|
||||||
|
{
|
||||||
|
scrollbar.gameObject.SetActive(showScrollBar && scroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果启用/禁用滚动后需要调整布局或滚动条大小,刷新布局
|
||||||
|
RequestLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Snap
|
||||||
|
{
|
||||||
|
get => snap;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// Snap 依赖于 Scroll(与原逻辑保持一致)
|
||||||
|
bool newSnap = value & scroll;
|
||||||
|
if (snap == newSnap) return;
|
||||||
|
snap = newSnap;
|
||||||
|
|
||||||
|
if (scroller != null)
|
||||||
|
{
|
||||||
|
scroller.Snap = snap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果开启了 snap,可以选做:立即对齐到最近项
|
||||||
|
// if (snap && scroller != null) SnapToNearestItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float ScrollSpeed
|
||||||
|
{
|
||||||
|
get => scrollSpeed;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Mathf.Approximately(scrollSpeed, value)) return;
|
||||||
|
scrollSpeed = value;
|
||||||
|
|
||||||
|
if (scroller != null)
|
||||||
|
{
|
||||||
|
scroller.ScrollSpeed = scrollSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float WheelSpeed
|
||||||
|
{
|
||||||
|
get => wheelSpeed;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Mathf.Approximately(wheelSpeed, value)) return;
|
||||||
|
wheelSpeed = value;
|
||||||
|
|
||||||
|
if (scroller != null)
|
||||||
|
{
|
||||||
|
scroller.WheelSpeed = wheelSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Public Properties - Components
|
||||||
|
|
||||||
|
public ViewHolder[] Templates
|
||||||
|
{
|
||||||
|
get => templates;
|
||||||
|
set => templates = value;
|
||||||
|
}
|
||||||
|
|
||||||
public RectTransform Content
|
public RectTransform Content
|
||||||
{
|
{
|
||||||
@ -38,328 +190,354 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField] private Vector2 spacing;
|
public Scrollbar Scrollbar => scrollbar;
|
||||||
|
|
||||||
public Vector2 Spacing
|
|
||||||
{
|
|
||||||
get => spacing;
|
|
||||||
set => spacing = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeField] private Vector2 padding;
|
|
||||||
|
|
||||||
public Vector2 Padding
|
|
||||||
{
|
|
||||||
get => padding;
|
|
||||||
set => padding = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeField] private bool scroll;
|
|
||||||
|
|
||||||
public bool Scroll
|
|
||||||
{
|
|
||||||
get => scroll;
|
|
||||||
set => scroll = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeField] private bool snap;
|
|
||||||
|
|
||||||
public bool Snap
|
|
||||||
{
|
|
||||||
get => snap;
|
|
||||||
set => snap = value & scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeField, Range(1f, 50f)] private float scrollSpeed = 7f;
|
|
||||||
|
|
||||||
public float ScrollSpeed
|
|
||||||
{
|
|
||||||
get => scrollSpeed;
|
|
||||||
set => scrollSpeed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeField, Range(10f, 50f)] private float wheelSpeed = 30f;
|
|
||||||
|
|
||||||
public float WheeelSpeed
|
|
||||||
{
|
|
||||||
get => wheelSpeed;
|
|
||||||
set => wheelSpeed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeField] private ViewHolder[] templates;
|
|
||||||
|
|
||||||
public ViewHolder[] Templates
|
|
||||||
{
|
|
||||||
get => templates;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[SerializeField] private string _scrollerTypeName;
|
|
||||||
|
|
||||||
[SerializeReference] private Scroller _scroller;
|
|
||||||
|
|
||||||
[SerializeField] private bool _showScrollBar;
|
|
||||||
[SerializeReference] private Scrollbar _scrollbar;
|
|
||||||
|
|
||||||
|
|
||||||
private ViewProvider viewProvider;
|
|
||||||
|
|
||||||
[SerializeField] private string _layoutManagerTypeName;
|
|
||||||
|
|
||||||
[SerializeReference] private LayoutManager _layoutManager;
|
|
||||||
|
|
||||||
|
|
||||||
private int startIndex, endIndex;
|
|
||||||
private int currentIndex;
|
|
||||||
|
|
||||||
public Scroller Scroller => _scroller;
|
|
||||||
|
|
||||||
public int CurrentIndex
|
|
||||||
{
|
|
||||||
get => currentIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanScroll => true;
|
|
||||||
|
|
||||||
|
public Scroller Scroller => scroller;
|
||||||
|
|
||||||
public ViewProvider ViewProvider
|
public ViewProvider ViewProvider
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
viewProvider ??= templates.Length > 1 ? new MixedViewProvider(this, templates) : new SimpleViewProvider(this, templates);
|
if (viewProvider == null)
|
||||||
|
{
|
||||||
|
viewProvider = templates.Length > 1
|
||||||
|
? new MixedViewProvider(this, templates)
|
||||||
|
: new SimpleViewProvider(this, templates);
|
||||||
|
}
|
||||||
|
|
||||||
return viewProvider;
|
return viewProvider;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scrollbar Scrollbar => _scrollbar;
|
#endregion
|
||||||
|
|
||||||
private IAdapter _adapter;
|
#region Public Properties - State
|
||||||
|
|
||||||
|
public IAdapter RecyclerViewAdapter { get; set; }
|
||||||
|
|
||||||
|
public int CurrentIndex
|
||||||
|
{
|
||||||
|
get => currentIndex;
|
||||||
|
set => currentIndex = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
public Action<int> OnIndexChanged;
|
public Action<int> OnIndexChanged;
|
||||||
public Action OnScrollValueChanged;
|
public Action OnScrollValueChanged;
|
||||||
public Action OnMoveingChanged;
|
|
||||||
|
|
||||||
private void OnValidate()
|
#endregion
|
||||||
{
|
|
||||||
if (_scroller != null)
|
|
||||||
{
|
|
||||||
_scroller.ScrollSpeed = scrollSpeed;
|
|
||||||
_scroller.WheelSpeed = wheelSpeed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnScrollChanged(float pos)
|
#region Unity Lifecycle
|
||||||
{
|
|
||||||
_layoutManager.UpdateLayout();
|
|
||||||
|
|
||||||
if (Scrollbar != null)
|
|
||||||
{
|
|
||||||
Scrollbar.SetValueWithoutNotify(pos / _scroller.MaxPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_layoutManager.IsFullInvisibleStart(startIndex))
|
|
||||||
{
|
|
||||||
viewProvider.RemoveViewHolder(startIndex);
|
|
||||||
startIndex += _layoutManager.Unit;
|
|
||||||
}
|
|
||||||
else if (_layoutManager.IsFullVisibleStart(startIndex))
|
|
||||||
{
|
|
||||||
if (startIndex == 0)
|
|
||||||
{
|
|
||||||
// TODO Do something, eg: Refresh
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
startIndex -= _layoutManager.Unit;
|
|
||||||
viewProvider.CreateViewHolder(startIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_layoutManager.IsFullInvisibleEnd(endIndex))
|
|
||||||
{
|
|
||||||
viewProvider.RemoveViewHolder(endIndex);
|
|
||||||
endIndex -= _layoutManager.Unit;
|
|
||||||
}
|
|
||||||
else if (_layoutManager.IsFullVisibleEnd(endIndex))
|
|
||||||
{
|
|
||||||
if (endIndex >= viewProvider.GetItemCount() - _layoutManager.Unit)
|
|
||||||
{
|
|
||||||
// TODO Do something, eg: Load More
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
endIndex += _layoutManager.Unit;
|
|
||||||
viewProvider.CreateViewHolder(endIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用滚动条快速定位时,刷新整个列表
|
|
||||||
if (!_layoutManager.IsVisible(startIndex) || !_layoutManager.IsVisible(endIndex))
|
|
||||||
{
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
_layoutManager.DoItemAnimation();
|
|
||||||
|
|
||||||
OnScrollValueChanged?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnMoveing()
|
|
||||||
{
|
|
||||||
OnMoveingChanged?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnMoveStoped()
|
|
||||||
{
|
|
||||||
if (Snap)
|
|
||||||
{
|
|
||||||
SnapTo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnScrollbarChanged(float ratio)
|
|
||||||
{
|
|
||||||
_scroller.ScrollToRatio(ratio);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnScrollbarDragEnd()
|
|
||||||
{
|
|
||||||
if (_scroller.Position < _scroller.MaxPosition)
|
|
||||||
{
|
|
||||||
if (Snap)
|
|
||||||
{
|
|
||||||
SnapTo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < templates.Length; i++)
|
InitializeTemplates();
|
||||||
{
|
ConfigureScroller();
|
||||||
templates[i].gameObject.SetActive(false);
|
ConfigureScrollbar();
|
||||||
}
|
|
||||||
|
|
||||||
ConfigScroller();
|
|
||||||
ConfigScrollbar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
#endregion
|
||||||
|
|
||||||
|
#region Initialization
|
||||||
|
|
||||||
|
private void InitializeTemplates()
|
||||||
{
|
{
|
||||||
viewProvider?.Dispose();
|
if (templates == null) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < templates.Length; i++)
|
||||||
|
{
|
||||||
|
if (templates[i] != null)
|
||||||
|
{
|
||||||
|
templates[i].gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureScroller()
|
||||||
|
{
|
||||||
|
if (scroller == null) return;
|
||||||
|
|
||||||
|
scroller.ScrollSpeed = scrollSpeed;
|
||||||
|
scroller.WheelSpeed = wheelSpeed;
|
||||||
|
scroller.Snap = snap;
|
||||||
|
scroller.OnValueChanged.AddListener(OnScrollChanged);
|
||||||
|
scroller.OnMoveStoped.AddListener(OnMoveStoped);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureScrollbar()
|
||||||
|
{
|
||||||
|
if (!showScrollBar || scrollbar == null) return;
|
||||||
|
|
||||||
|
scrollbar.gameObject.SetActive(scroll);
|
||||||
|
scrollbar.onValueChanged.AddListener(OnScrollbarChanged);
|
||||||
|
|
||||||
|
var scrollbarEx = scrollbar.gameObject.GetComponent<ScrollbarEx>();
|
||||||
|
if (scrollbarEx == null)
|
||||||
|
{
|
||||||
|
scrollbarEx = scrollbar.gameObject.AddComponent<ScrollbarEx>();
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollbarEx.OnDragEnd = OnScrollbarDragEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods - Setup
|
||||||
|
|
||||||
|
public void SetAdapter(IAdapter adapter)
|
||||||
|
{
|
||||||
|
if (adapter == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Adapter cannot be null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecyclerViewAdapter = adapter;
|
||||||
|
ViewProvider.Adapter = adapter;
|
||||||
|
ViewProvider.LayoutManager = layoutManager;
|
||||||
|
|
||||||
|
layoutManager.RecyclerView = this;
|
||||||
|
layoutManager.Adapter = adapter;
|
||||||
|
layoutManager.ViewProvider = viewProvider;
|
||||||
|
layoutManager.Direction = direction;
|
||||||
|
layoutManager.Alignment = alignment;
|
||||||
|
layoutManager.Spacing = spacing;
|
||||||
|
layoutManager.Padding = padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
viewProvider?.Reset();
|
viewProvider?.Reset();
|
||||||
if (_scroller != null)
|
|
||||||
|
if (scroller != null)
|
||||||
{
|
{
|
||||||
_scroller.Position = 0;
|
scroller.Position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_scrollbar != null)
|
if (scrollbar != null)
|
||||||
{
|
{
|
||||||
_scrollbar.SetValueWithoutNotify(0);
|
scrollbar.SetValueWithoutNotify(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAdapter(IAdapter adapter)
|
#endregion
|
||||||
{
|
|
||||||
_adapter = adapter;
|
|
||||||
ViewProvider.Adapter = _adapter;
|
|
||||||
ViewProvider.LayoutManager = _layoutManager;
|
|
||||||
_layoutManager.RecyclerView = this;
|
|
||||||
_layoutManager.Adapter = _adapter;
|
|
||||||
_layoutManager.ViewProvider = viewProvider;
|
|
||||||
_layoutManager.Direction = direction;
|
|
||||||
_layoutManager.Alignment = alignment;
|
|
||||||
_layoutManager.Spacing = spacing;
|
|
||||||
_layoutManager.Padding = padding;
|
|
||||||
_layoutManager.CanScroll = CanScroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#region Public Methods - Layout
|
||||||
private void ConfigScroller()
|
|
||||||
{
|
|
||||||
if (_scroller != null)
|
|
||||||
{
|
|
||||||
_scroller.ScrollSpeed = scrollSpeed;
|
|
||||||
_scroller.WheelSpeed = wheelSpeed;
|
|
||||||
_scroller.Snap = Snap;
|
|
||||||
_scroller.OnValueChanged.AddListener(OnScrollChanged);
|
|
||||||
_scroller.OnMoveStoped.AddListener(OnMoveStoped);
|
|
||||||
_scroller.OnMoveing.AddListener(OnMoveing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConfigScrollbar()
|
|
||||||
{
|
|
||||||
if (_showScrollBar && _scrollbar != null)
|
|
||||||
{
|
|
||||||
_scrollbar.gameObject.SetActive(scroll);
|
|
||||||
_scrollbar.onValueChanged.AddListener(OnScrollbarChanged);
|
|
||||||
_scrollbar.gameObject.AddComponent<ScrollbarEx>().OnDragEnd = OnScrollbarDragEnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Refresh()
|
public void Refresh()
|
||||||
{
|
{
|
||||||
ViewProvider.Clear();
|
ViewProvider.Clear();
|
||||||
|
|
||||||
startIndex = _layoutManager.GetStartIndex();
|
startIndex = layoutManager.GetStartIndex();
|
||||||
endIndex = _layoutManager.GetEndIndex();
|
endIndex = layoutManager.GetEndIndex();
|
||||||
for (int i = startIndex; i <= endIndex; i += _layoutManager.Unit)
|
|
||||||
|
for (int i = startIndex; i <= endIndex; i += layoutManager.Unit)
|
||||||
{
|
{
|
||||||
ViewProvider.CreateViewHolder(i);
|
ViewProvider.CreateViewHolder(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
_layoutManager.DoItemAnimation();
|
layoutManager.DoItemAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestLayout()
|
public void RequestLayout()
|
||||||
{
|
{
|
||||||
_layoutManager.SetContentSize();
|
layoutManager.SetContentSize();
|
||||||
|
|
||||||
if (_scroller == null) return;
|
if (scroller == null) return;
|
||||||
|
|
||||||
_scroller.Direction = direction;
|
scroller.Direction = direction;
|
||||||
_scroller.ViewSize = _layoutManager.ViewportSize;
|
scroller.ViewSize = layoutManager.ViewportSize;
|
||||||
_scroller.ContentSize = _layoutManager.ContentSize;
|
scroller.ContentSize = layoutManager.ContentSize;
|
||||||
|
|
||||||
if (Scrollbar != null && _scroller.ContentSize != Vector2.zero)
|
UpdateScrollbarVisibility();
|
||||||
{
|
|
||||||
if ((direction == Direction.Vertical && _layoutManager.ContentSize.y <= _layoutManager.ViewportSize.y) ||
|
|
||||||
(direction == Direction.Horizontal && _layoutManager.ContentSize.x <= _layoutManager.ViewportSize.x) ||
|
|
||||||
(direction == Direction.Custom))
|
|
||||||
{
|
|
||||||
Scrollbar.gameObject.SetActive(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Scrollbar.gameObject.SetActive(true);
|
|
||||||
Scrollbar.direction = direction == Direction.Vertical ? Scrollbar.Direction.TopToBottom : Scrollbar.Direction.LeftToRight;
|
|
||||||
Scrollbar.size = direction == Direction.Vertical ? _scroller.ViewSize.y / _scroller.ContentSize.y : _scroller.ViewSize.x / _scroller.ContentSize.x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods - Scrolling
|
||||||
|
|
||||||
public float GetScrollPosition()
|
public float GetScrollPosition()
|
||||||
{
|
{
|
||||||
return _scroller ? _scroller.Position : 0;
|
return scroller != null ? scroller.Position : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScrollTo(int index, bool smooth = false)
|
public void ScrollTo(int index, bool smooth = false)
|
||||||
{
|
{
|
||||||
if (!scroll) return;
|
if (!scroll || scroller == null) return;
|
||||||
|
|
||||||
|
scroller.ScrollTo(layoutManager.IndexToPosition(index), smooth);
|
||||||
|
|
||||||
_scroller.ScrollTo(_layoutManager.IndexToPosition(index), smooth);
|
|
||||||
if (!smooth)
|
if (!smooth)
|
||||||
{
|
{
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
index %= _adapter.GetItemCount();
|
UpdateCurrentIndex(index);
|
||||||
index = index < 0 ? _adapter.GetItemCount() + index : index;
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods - Scroll Callbacks
|
||||||
|
|
||||||
|
private void OnScrollChanged(float position)
|
||||||
|
{
|
||||||
|
layoutManager.UpdateLayout();
|
||||||
|
UpdateScrollbarValue(position);
|
||||||
|
UpdateVisibleRange();
|
||||||
|
layoutManager.DoItemAnimation();
|
||||||
|
OnScrollValueChanged?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMoveStoped()
|
||||||
|
{
|
||||||
|
if (snap)
|
||||||
|
{
|
||||||
|
SnapToNearestItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScrollbarChanged(float ratio)
|
||||||
|
{
|
||||||
|
if (scroller != null)
|
||||||
|
{
|
||||||
|
scroller.ScrollToRatio(ratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScrollbarDragEnd()
|
||||||
|
{
|
||||||
|
if (scroller == null) return;
|
||||||
|
|
||||||
|
if (scroller.Position < scroller.MaxPosition && snap)
|
||||||
|
{
|
||||||
|
SnapToNearestItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods - Scroll Helpers
|
||||||
|
|
||||||
|
private void UpdateScrollbarValue(float position)
|
||||||
|
{
|
||||||
|
if (scrollbar != null && scroller != null)
|
||||||
|
{
|
||||||
|
float ratio = scroller.MaxPosition > 0 ? position / scroller.MaxPosition : 0;
|
||||||
|
scrollbar.SetValueWithoutNotify(ratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVisibleRange()
|
||||||
|
{
|
||||||
|
// Handle start index
|
||||||
|
if (layoutManager.IsFullInvisibleStart(startIndex))
|
||||||
|
{
|
||||||
|
viewProvider.RemoveViewHolder(startIndex);
|
||||||
|
startIndex += layoutManager.Unit;
|
||||||
|
}
|
||||||
|
else if (layoutManager.IsFullVisibleStart(startIndex))
|
||||||
|
{
|
||||||
|
if (startIndex == 0)
|
||||||
|
{
|
||||||
|
// TODO: Implement refresh logic
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startIndex -= layoutManager.Unit;
|
||||||
|
viewProvider.CreateViewHolder(startIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle end index
|
||||||
|
if (layoutManager.IsFullInvisibleEnd(endIndex))
|
||||||
|
{
|
||||||
|
viewProvider.RemoveViewHolder(endIndex);
|
||||||
|
endIndex -= layoutManager.Unit;
|
||||||
|
}
|
||||||
|
else if (layoutManager.IsFullVisibleEnd(endIndex))
|
||||||
|
{
|
||||||
|
if (endIndex >= viewProvider.GetItemCount() - layoutManager.Unit)
|
||||||
|
{
|
||||||
|
// TODO: Implement load more logic
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endIndex += layoutManager.Unit;
|
||||||
|
viewProvider.CreateViewHolder(endIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh if out of visible range
|
||||||
|
if (!layoutManager.IsVisible(startIndex) || !layoutManager.IsVisible(endIndex))
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateScrollbarVisibility()
|
||||||
|
{
|
||||||
|
if (scrollbar == null || scroller == null || layoutManager.ContentSize == Vector2.zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool shouldShow = ShouldShowScrollbar();
|
||||||
|
scrollbar.gameObject.SetActive(shouldShow);
|
||||||
|
|
||||||
|
if (shouldShow)
|
||||||
|
{
|
||||||
|
ConfigureScrollbarDirection();
|
||||||
|
ConfigureScrollbarSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldShowScrollbar()
|
||||||
|
{
|
||||||
|
if (direction == Direction.Custom) return false;
|
||||||
|
|
||||||
|
if (direction == Direction.Vertical)
|
||||||
|
{
|
||||||
|
return layoutManager.ContentSize.y > layoutManager.ViewportSize.y;
|
||||||
|
}
|
||||||
|
else // Horizontal
|
||||||
|
{
|
||||||
|
return layoutManager.ContentSize.x > layoutManager.ViewportSize.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureScrollbarDirection()
|
||||||
|
{
|
||||||
|
scrollbar.direction = direction == Direction.Vertical
|
||||||
|
? Scrollbar.Direction.TopToBottom
|
||||||
|
: Scrollbar.Direction.LeftToRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureScrollbarSize()
|
||||||
|
{
|
||||||
|
if (direction == Direction.Vertical)
|
||||||
|
{
|
||||||
|
scrollbar.size = scroller.ViewSize.y / scroller.ContentSize.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scrollbar.size = scroller.ViewSize.x / scroller.ContentSize.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SnapToNearestItem()
|
||||||
|
{
|
||||||
|
int index = layoutManager.PositionToIndex(GetScrollPosition());
|
||||||
|
ScrollTo(index, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCurrentIndex(int index)
|
||||||
|
{
|
||||||
|
if (RecyclerViewAdapter == null) return;
|
||||||
|
|
||||||
|
int itemCount = RecyclerViewAdapter.GetItemCount();
|
||||||
|
index %= itemCount;
|
||||||
|
index = index < 0 ? itemCount + index : index;
|
||||||
|
|
||||||
if (currentIndex != index)
|
if (currentIndex != index)
|
||||||
{
|
{
|
||||||
@ -368,11 +546,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
private void SnapTo()
|
|
||||||
{
|
|
||||||
var index = _layoutManager.PositionToIndex(GetScrollPosition());
|
|
||||||
ScrollTo(index, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ MonoImporter:
|
|||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
||||||
executionOrder: 0
|
executionOrder: 0
|
||||||
icon: {fileID: 2800000, guid: a01ce47da31a2e0438fd8d38b203c0d5, type: 3}
|
icon: {instanceID: 0}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
assetBundleVariant:
|
assetBundleVariant:
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
[Serializable]
|
|
||||||
public class CircleScroller : Scroller
|
public class CircleScroller : Scroller
|
||||||
{
|
{
|
||||||
private Vector2 centerPosition;
|
private Vector2 centerPosition;
|
||||||
|
|||||||
@ -9,19 +9,7 @@ namespace AlicizaX.UI
|
|||||||
void ScrollTo(float position, bool smooth = false);
|
void ScrollTo(float position, bool smooth = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScrollerEvent : UnityEvent<float>
|
public class ScrollerEvent : UnityEvent<float> { }
|
||||||
{
|
public class MoveStopEvent : UnityEvent { }
|
||||||
}
|
public class DraggingEvent : UnityEvent<bool> { }
|
||||||
|
|
||||||
public class MoveStopEvent : UnityEvent
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DraggingEvent : UnityEvent<bool>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MoveingEvent : UnityEvent
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,18 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
[Serializable]
|
|
||||||
public class Scroller : MonoBehaviour, IScroller, IBeginDragHandler, IEndDragHandler, IDragHandler, IScrollHandler
|
public class Scroller : MonoBehaviour, IScroller, IBeginDragHandler, IEndDragHandler, IDragHandler, IScrollHandler
|
||||||
{
|
{
|
||||||
protected float position;
|
protected float position;
|
||||||
|
public float Position { get => position; set => position = value; }
|
||||||
public float Position
|
|
||||||
{
|
|
||||||
get => position;
|
|
||||||
set => position = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected float velocity;
|
protected float velocity;
|
||||||
public float Velocity => velocity;
|
public float Velocity => velocity;
|
||||||
|
|
||||||
protected Direction direction;
|
protected Direction direction;
|
||||||
|
|
||||||
public Direction Direction
|
public Direction Direction
|
||||||
{
|
{
|
||||||
get => direction;
|
get => direction;
|
||||||
@ -31,7 +23,6 @@ namespace AlicizaX.UI
|
|||||||
/// 内容所需要大小
|
/// 内容所需要大小
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected Vector2 contentSize;
|
protected Vector2 contentSize;
|
||||||
|
|
||||||
public Vector2 ContentSize
|
public Vector2 ContentSize
|
||||||
{
|
{
|
||||||
get => contentSize;
|
get => contentSize;
|
||||||
@ -42,7 +33,6 @@ namespace AlicizaX.UI
|
|||||||
/// 所在 View 的真实大小
|
/// 所在 View 的真实大小
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected Vector2 viewSize;
|
protected Vector2 viewSize;
|
||||||
|
|
||||||
public Vector2 ViewSize
|
public Vector2 ViewSize
|
||||||
{
|
{
|
||||||
get => viewSize;
|
get => viewSize;
|
||||||
@ -50,7 +40,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected float scrollSpeed = 1f;
|
protected float scrollSpeed = 1f;
|
||||||
|
|
||||||
public float ScrollSpeed
|
public float ScrollSpeed
|
||||||
{
|
{
|
||||||
get => scrollSpeed;
|
get => scrollSpeed;
|
||||||
@ -58,7 +47,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected float wheelSpeed = 30f;
|
protected float wheelSpeed = 30f;
|
||||||
|
|
||||||
public float WheelSpeed
|
public float WheelSpeed
|
||||||
{
|
{
|
||||||
get => wheelSpeed;
|
get => wheelSpeed;
|
||||||
@ -66,7 +54,6 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected bool snap;
|
protected bool snap;
|
||||||
|
|
||||||
public bool Snap
|
public bool Snap
|
||||||
{
|
{
|
||||||
get => snap;
|
get => snap;
|
||||||
@ -76,38 +63,21 @@ namespace AlicizaX.UI
|
|||||||
protected ScrollerEvent scrollerEvent = new();
|
protected ScrollerEvent scrollerEvent = new();
|
||||||
protected MoveStopEvent moveStopEvent = new();
|
protected MoveStopEvent moveStopEvent = new();
|
||||||
protected DraggingEvent draggingEvent = new();
|
protected DraggingEvent draggingEvent = new();
|
||||||
protected MoveingEvent moveingEvent = new();
|
|
||||||
|
|
||||||
public float MaxPosition => direction == Direction.Vertical ? Mathf.Max(contentSize.y - viewSize.y, 0) : Mathf.Max(contentSize.x - viewSize.x, 0);
|
public float MaxPosition => direction == Direction.Vertical ?
|
||||||
|
Mathf.Max(contentSize.y - viewSize.y, 0) :
|
||||||
|
Mathf.Max(contentSize.x - viewSize.x, 0);
|
||||||
|
|
||||||
public float ViewLength => direction == Direction.Vertical ? viewSize.y : viewSize.x;
|
public float ViewLength => direction == Direction.Vertical ? viewSize.y : viewSize.x;
|
||||||
|
|
||||||
public MoveingEvent OnMoveing
|
public ScrollerEvent OnValueChanged { get => scrollerEvent; set => scrollerEvent = value; }
|
||||||
{
|
|
||||||
get => moveingEvent;
|
|
||||||
set => moveingEvent = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScrollerEvent OnValueChanged
|
public MoveStopEvent OnMoveStoped { get => moveStopEvent; set => moveStopEvent = value; }
|
||||||
{
|
|
||||||
get => scrollerEvent;
|
|
||||||
set => scrollerEvent = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MoveStopEvent OnMoveStoped
|
public DraggingEvent OnDragging { get => draggingEvent; set => draggingEvent = value; }
|
||||||
{
|
|
||||||
get => moveStopEvent;
|
|
||||||
set => moveStopEvent = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DraggingEvent OnDragging
|
|
||||||
{
|
|
||||||
get => draggingEvent;
|
|
||||||
set => draggingEvent = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 停止滑动的时间,但此时并未释放鼠标按键
|
// 停止滑动的时间,但此时并未释放鼠标按键
|
||||||
private float dragStopTime = 0f;
|
public float dragStopTime = 0f;
|
||||||
|
|
||||||
public virtual void ScrollTo(float position, bool smooth = false)
|
public virtual void ScrollTo(float position, bool smooth = false)
|
||||||
{
|
{
|
||||||
@ -151,10 +121,9 @@ namespace AlicizaX.UI
|
|||||||
position += velocity;
|
position += velocity;
|
||||||
|
|
||||||
OnValueChanged?.Invoke(position);
|
OnValueChanged?.Invoke(position);
|
||||||
OnMoveing?.Invoke();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnScrolled(PointerEventData eventData)
|
public void OnScroll(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
StopAllCoroutines();
|
StopAllCoroutines();
|
||||||
|
|
||||||
@ -163,7 +132,7 @@ namespace AlicizaX.UI
|
|||||||
position += velocity;
|
position += velocity;
|
||||||
|
|
||||||
OnValueChanged?.Invoke(position);
|
OnValueChanged?.Invoke(position);
|
||||||
OnMoveing?.Invoke();
|
Inertia();
|
||||||
Elastic();
|
Elastic();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +153,6 @@ namespace AlicizaX.UI
|
|||||||
{
|
{
|
||||||
rate = Mathf.Max(0, 1 - (Mathf.Abs(position - MaxPosition) / ViewLength));
|
rate = Mathf.Max(0, 1 - (Mathf.Abs(position - MaxPosition) / ViewLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rate;
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,11 +241,5 @@ namespace AlicizaX.UI
|
|||||||
position = targetPos;
|
position = targetPos;
|
||||||
OnValueChanged?.Invoke(position);
|
OnValueChanged?.Invoke(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IScrollHandler.OnScroll(PointerEventData eventData)
|
|
||||||
{
|
|
||||||
OnScrolled(eventData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,7 +74,7 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UGList
|
public static class UGListCreateHelper
|
||||||
{
|
{
|
||||||
public static UGList<TData> Create<TData>(RecyclerView recyclerView, Action<TData> onItemClick = null) where TData : ISimpleViewData
|
public static UGList<TData> Create<TData>(RecyclerView recyclerView, Action<TData> onItemClick = null) where TData : ISimpleViewData
|
||||||
=> new UGList<TData>(recyclerView, onItemClick);
|
=> new UGList<TData>(recyclerView, onItemClick);
|
||||||
3
Runtime/RecyclerView/UGList.cs.meta
Normal file
3
Runtime/RecyclerView/UGList.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fd094e3cb2194cb193221ea9436a169a
|
||||||
|
timeCreated: 1766729620
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 369d2829a7a2462ba93212b3d8afe0fa
|
|
||||||
timeCreated: 1763615925
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 19892a10438348b3b7e7cac3e2201b9e
|
|
||||||
timeCreated: 1763615934
|
|
||||||
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SimpleObjectPool;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using SimpleObjectPool;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using AlicizaX.UI.Runtime;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX.UI
|
namespace AlicizaX.UI
|
||||||
@ -8,7 +6,7 @@ namespace AlicizaX.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 提供和管理 ViewHolder
|
/// 提供和管理 ViewHolder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ViewProvider : IDisposable
|
public abstract class ViewProvider
|
||||||
{
|
{
|
||||||
private readonly List<ViewHolder> viewHolders = new();
|
private readonly List<ViewHolder> viewHolders = new();
|
||||||
|
|
||||||
@ -44,10 +42,10 @@ namespace AlicizaX.UI
|
|||||||
|
|
||||||
string viewName = Adapter.GetViewName(i);
|
string viewName = Adapter.GetViewName(i);
|
||||||
var viewHolder = Allocate(viewName);
|
var viewHolder = Allocate(viewName);
|
||||||
viewHolder.OnStart();
|
|
||||||
viewHolder.Name = viewName;
|
viewHolder.Name = viewName;
|
||||||
viewHolder.Index = i;
|
viewHolder.Index = i;
|
||||||
viewHolders.Add(viewHolder);
|
viewHolders.Add(viewHolder);
|
||||||
|
|
||||||
LayoutManager.Layout(viewHolder, i);
|
LayoutManager.Layout(viewHolder, i);
|
||||||
Adapter.OnBindViewHolder(viewHolder, i);
|
Adapter.OnBindViewHolder(viewHolder, i);
|
||||||
}
|
}
|
||||||
@ -131,15 +129,5 @@ namespace AlicizaX.UI
|
|||||||
{
|
{
|
||||||
return Adapter == null ? 0 : Adapter.GetItemCount();
|
return Adapter == null ? 0 : Adapter.GetItemCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
foreach (var viewHolder in viewHolders)
|
|
||||||
{
|
|
||||||
Free(viewHolder.Name, viewHolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewHolders.Clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user