using UnityEngine; namespace AlicizaX.UI.RecyclerView { public class AlignableLinearLayoutManager : LinearLayoutManager { [SerializeField] private float alignmentRatio = 0f; // 对齐比例 (0=顶部, 1=底部, 0.5=居中) private float CalculateAlignmentOffset() { if (direction == Direction.Vertical) { // 垂直布局:计算视口高度相关的偏移 float viewportHeight = viewportSize.y; float itemHeight = lineHeight; return alignmentRatio * (viewportHeight - itemHeight); } else { // 水平布局:计算视口宽度相关的偏移 float viewportWidth = viewportSize.x; float itemWidth = lineHeight; // 注意:水平布局中lineHeight表示宽度 return alignmentRatio * (viewportWidth - itemWidth); } } public override Vector2 CalculatePosition(int index) { float position; float alignmentOffset = CalculateAlignmentOffset(); if (direction == Direction.Vertical) { position = index * (lineHeight + spacing.y) - ScrollPosition + alignmentOffset; return new Vector2(0, position + padding.y); } position = index * (lineHeight + spacing.x) - ScrollPosition + alignmentOffset; var a = new Vector2(position + padding.x, 0); Debug.Log("Calcu" + a); return a; } public override float IndexToPosition(int index) { if (index < 0 || index >= adapter.GetItemCount()) return 0; float len, viewLength, position; float alignmentOffset = CalculateAlignmentOffset(); if (direction == Direction.Vertical) { len = index * (lineHeight + spacing.y) + alignmentOffset - ((lineHeight + spacing.y) * 2); viewLength = viewportSize.y; position = len + viewLength > contentSize.y ? contentSize.y - viewportSize.y : len; } else { len = index * (lineHeight + spacing.x) + alignmentOffset; viewLength = viewportSize.x; position = len + viewLength > contentSize.x ? contentSize.x - viewportSize.x : len; } Debug.Log($"index:{index} len:{len} view:{viewLength} position:{position}"); return position; } } }