fix
This commit is contained in:
parent
26c205ddc0
commit
ca46f80d67
@ -378,6 +378,87 @@ namespace AlicizaX.UI
|
||||
UpdateCurrentIndex(index);
|
||||
}
|
||||
|
||||
public void ScrollToWithAlignment(int index, ScrollAlignment alignment, float offset = 0f, bool smooth = false, float duration = 0.3f)
|
||||
{
|
||||
if (!scroll || scroller == null) return;
|
||||
|
||||
float targetPosition = CalculateScrollPositionWithAlignment(index, alignment, offset);
|
||||
|
||||
if (UGListExtensions.DebugScrollTo)
|
||||
{
|
||||
Debug.Log($"[RecyclerView] ScrollToWithAlignment: index={index}, alignment={alignment}, offset={offset}, targetPosition={targetPosition}, maxPosition={scroller.MaxPosition}");
|
||||
}
|
||||
|
||||
if (duration > 0 && smooth)
|
||||
{
|
||||
scroller.ScrollTo(targetPosition, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
scroller.ScrollTo(targetPosition, smooth);
|
||||
}
|
||||
|
||||
if (!smooth)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
UpdateCurrentIndex(index);
|
||||
}
|
||||
|
||||
private float CalculateScrollPositionWithAlignment(int index, ScrollAlignment alignment, float offset)
|
||||
{
|
||||
if (RecyclerViewAdapter == null || index < 0 || index >= RecyclerViewAdapter.GetItemCount())
|
||||
{
|
||||
return scroller.Position;
|
||||
}
|
||||
|
||||
float itemSize = GetItemSize(index);
|
||||
float viewportLength = direction == Direction.Vertical ? layoutManager.ViewportSize.y : layoutManager.ViewportSize.x;
|
||||
float contentLength = direction == Direction.Vertical ? layoutManager.ContentSize.y : layoutManager.ContentSize.x;
|
||||
|
||||
// Calculate the raw position of the item (without any clamping)
|
||||
float itemPosition = CalculateRawItemPosition(index);
|
||||
|
||||
float targetPosition = alignment switch
|
||||
{
|
||||
ScrollAlignment.Start => itemPosition,
|
||||
ScrollAlignment.Center => itemPosition - (viewportLength - itemSize) / 2f,
|
||||
ScrollAlignment.End => itemPosition - viewportLength + itemSize,
|
||||
_ => itemPosition
|
||||
};
|
||||
|
||||
// Apply custom offset
|
||||
targetPosition += offset;
|
||||
|
||||
if (UGListExtensions.DebugScrollTo)
|
||||
{
|
||||
Debug.Log($"[RecyclerView] CalculateScrollPosition: index={index}, itemPosition={itemPosition}, itemSize={itemSize}, viewportLength={viewportLength}, contentLength={contentLength}, targetPosition={targetPosition}, maxPosition={scroller.MaxPosition}");
|
||||
}
|
||||
|
||||
// Clamp to valid scroll range
|
||||
return Mathf.Clamp(targetPosition, 0, scroller.MaxPosition);
|
||||
}
|
||||
|
||||
private float CalculateRawItemPosition(int index)
|
||||
{
|
||||
// Get spacing based on direction
|
||||
Vector2 spacing = layoutManager.Spacing;
|
||||
Vector2 padding = layoutManager.Padding;
|
||||
float itemSize = GetItemSize(index);
|
||||
float spacingValue = direction == Direction.Vertical ? spacing.y : spacing.x;
|
||||
float paddingValue = direction == Direction.Vertical ? padding.y : padding.x;
|
||||
|
||||
// Calculate raw position without clamping
|
||||
return index * (itemSize + spacingValue) + paddingValue;
|
||||
}
|
||||
|
||||
private float GetItemSize(int index)
|
||||
{
|
||||
Vector2 itemSize = ViewProvider.CalculateViewSize(index);
|
||||
return direction == Direction.Vertical ? itemSize.y : itemSize.x;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods - Scroll Callbacks
|
||||
|
||||
23
Runtime/RecyclerView/ScrollAlignment.cs
Normal file
23
Runtime/RecyclerView/ScrollAlignment.cs
Normal file
@ -0,0 +1,23 @@
|
||||
namespace AlicizaX.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines how an item should be aligned when scrolling to it
|
||||
/// </summary>
|
||||
public enum ScrollAlignment
|
||||
{
|
||||
/// <summary>
|
||||
/// Align item to the top/left of the viewport
|
||||
/// </summary>
|
||||
Start,
|
||||
|
||||
/// <summary>
|
||||
/// Align item to the center of the viewport
|
||||
/// </summary>
|
||||
Center,
|
||||
|
||||
/// <summary>
|
||||
/// Align item to the bottom/right of the viewport
|
||||
/// </summary>
|
||||
End
|
||||
}
|
||||
}
|
||||
11
Runtime/RecyclerView/ScrollAlignment.cs.meta
Normal file
11
Runtime/RecyclerView/ScrollAlignment.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d17e4def4547e70499c0f63802da2772
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
94
Runtime/RecyclerView/UGListExtensions.cs
Normal file
94
Runtime/RecyclerView/UGListExtensions.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for UGList to provide enhanced scrolling functionality
|
||||
/// </summary>
|
||||
public static class UGListExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Enable debug logging for ScrollTo operations
|
||||
/// </summary>
|
||||
public static bool DebugScrollTo { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls to a specific item with alignment and animation options
|
||||
/// </summary>
|
||||
/// <param name="ugList">The UGList instance</param>
|
||||
/// <param name="index">The index of the item to scroll to</param>
|
||||
/// <param name="alignment">How to align the item in the viewport (Start, Center, or End)</param>
|
||||
/// <param name="offset">Additional offset in pixels to apply after alignment</param>
|
||||
/// <param name="smooth">Whether to animate the scroll</param>
|
||||
/// <param name="duration">Animation duration in seconds (only used when smooth is true)</param>
|
||||
public static void ScrollTo<TData, TAdapter>(
|
||||
this UGListBase<TData, TAdapter> ugList,
|
||||
int index,
|
||||
ScrollAlignment alignment = ScrollAlignment.Start,
|
||||
float offset = 0f,
|
||||
bool smooth = false,
|
||||
float duration = 0.3f)
|
||||
where TAdapter : Adapter<TData>
|
||||
where TData : ISimpleViewData
|
||||
{
|
||||
if (ugList?.RecyclerView == null)
|
||||
{
|
||||
Debug.LogWarning("UGList or RecyclerView is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DebugScrollTo)
|
||||
{
|
||||
Debug.Log($"[UGListExtensions] ScrollTo: index={index}, alignment={alignment}, offset={offset}, smooth={smooth}, duration={duration}");
|
||||
}
|
||||
|
||||
ugList.RecyclerView.ScrollToWithAlignment(index, alignment, offset, smooth, duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls to a specific item and aligns it at the start (top/left) of the viewport
|
||||
/// </summary>
|
||||
public static void ScrollToStart<TData, TAdapter>(
|
||||
this UGListBase<TData, TAdapter> ugList,
|
||||
int index,
|
||||
float offset = 0f,
|
||||
bool smooth = false,
|
||||
float duration = 0.3f)
|
||||
where TAdapter : Adapter<TData>
|
||||
where TData : ISimpleViewData
|
||||
{
|
||||
ugList.ScrollTo(index, ScrollAlignment.Start, offset, smooth, duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls to a specific item and aligns it at the center of the viewport
|
||||
/// </summary>
|
||||
public static void ScrollToCenter<TData, TAdapter>(
|
||||
this UGListBase<TData, TAdapter> ugList,
|
||||
int index,
|
||||
float offset = 0f,
|
||||
bool smooth = false,
|
||||
float duration = 0.3f)
|
||||
where TAdapter : Adapter<TData>
|
||||
where TData : ISimpleViewData
|
||||
{
|
||||
ugList.ScrollTo(index, ScrollAlignment.Center, offset, smooth, duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls to a specific item and aligns it at the end (bottom/right) of the viewport
|
||||
/// </summary>
|
||||
public static void ScrollToEnd<TData, TAdapter>(
|
||||
this UGListBase<TData, TAdapter> ugList,
|
||||
int index,
|
||||
float offset = 0f,
|
||||
bool smooth = false,
|
||||
float duration = 0.3f)
|
||||
where TAdapter : Adapter<TData>
|
||||
where TData : ISimpleViewData
|
||||
{
|
||||
ugList.ScrollTo(index, ScrollAlignment.End, offset, smooth, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/RecyclerView/UGListExtensions.cs.meta
Normal file
3
Runtime/RecyclerView/UGListExtensions.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8f3c4e7d9b24f1a8c5e2d6f3a7b9c1e
|
||||
timeCreated: 1735197600
|
||||
31
Runtime/RecyclerView/readme.md
Normal file
31
Runtime/RecyclerView/readme.md
Normal file
@ -0,0 +1,31 @@
|
||||
Simple Test
|
||||
|
||||
public class TestData : ISimpleViewData
|
||||
{
|
||||
public string Name;
|
||||
}
|
||||
|
||||
public class TestRecyclerView : MonoBehaviour
|
||||
{
|
||||
public RecyclerView itemListView;
|
||||
public UGList<TestData> list;
|
||||
|
||||
void Start()
|
||||
{
|
||||
list = UGListCreateHelper.Create<TestData>(itemListView, OnBtnItemClick);
|
||||
|
||||
List<TestData> datas = new();
|
||||
for (int i = 0; i < 150; i++)
|
||||
{
|
||||
datas.Add(new TestData { Name = $"Item {i}" });
|
||||
}
|
||||
|
||||
list.Data = datas;
|
||||
}
|
||||
|
||||
private void OnBtnItemClick(TestData obj)
|
||||
{
|
||||
Debug.Log(obj.Name);
|
||||
}
|
||||
|
||||
}
|
||||
3
Runtime/RecyclerView/readme.md.meta
Normal file
3
Runtime/RecyclerView/readme.md.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0bd5104eb4344798791ff94b29eb63b
|
||||
timeCreated: 1766730473
|
||||
Loading…
Reference in New Issue
Block a user