虚拟列表增加动态ScrollBarWenScrollable
This commit is contained in:
parent
619efa0d4d
commit
8c5ab0b24a
@ -57,6 +57,7 @@ namespace AlicizaX.UI.Editor
|
|||||||
|
|
||||||
private SerializedProperty _templates;
|
private SerializedProperty _templates;
|
||||||
private SerializedProperty _showScrollBar;
|
private SerializedProperty _showScrollBar;
|
||||||
|
private SerializedProperty _showScrollBarOnlyWhenScrollable;
|
||||||
private SerializedProperty _scrollbar;
|
private SerializedProperty _scrollbar;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -120,6 +121,7 @@ namespace AlicizaX.UI.Editor
|
|||||||
{
|
{
|
||||||
_templates = serializedObject.FindProperty("templates");
|
_templates = serializedObject.FindProperty("templates");
|
||||||
_showScrollBar = serializedObject.FindProperty("showScrollBar");
|
_showScrollBar = serializedObject.FindProperty("showScrollBar");
|
||||||
|
_showScrollBarOnlyWhenScrollable = serializedObject.FindProperty("showScrollBarOnlyWhenScrollable");
|
||||||
_scrollbar = serializedObject.FindProperty("scrollbar");
|
_scrollbar = serializedObject.FindProperty("scrollbar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,6 +305,13 @@ namespace AlicizaX.UI.Editor
|
|||||||
{
|
{
|
||||||
HandleScrollBarToggle();
|
HandleScrollBarToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_showScrollBar.boolValue)
|
||||||
|
{
|
||||||
|
EditorGUILayout.PropertyField(
|
||||||
|
_showScrollBarOnlyWhenScrollable,
|
||||||
|
new GUIContent("Only When Scrollable", "Hide the scrollbar and disable list scrolling when content does not overflow the viewport."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,7 @@ namespace AlicizaX.UI
|
|||||||
[HideInInspector] [SerializeField] private ViewHolder[] templates;
|
[HideInInspector] [SerializeField] private ViewHolder[] templates;
|
||||||
[HideInInspector] [SerializeField] private RectTransform content;
|
[HideInInspector] [SerializeField] private RectTransform content;
|
||||||
[HideInInspector] [SerializeField] private bool showScrollBar;
|
[HideInInspector] [SerializeField] private bool showScrollBar;
|
||||||
|
[HideInInspector] [SerializeField] private bool showScrollBarOnlyWhenScrollable;
|
||||||
[HideInInspector] [SerializeField] private Scrollbar scrollbar;
|
[HideInInspector] [SerializeField] private Scrollbar scrollbar;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -200,6 +201,20 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否仅在内容超出可视区域时显示滚动条并允许滚动
|
||||||
|
/// </summary>
|
||||||
|
public bool ShowScrollBarOnlyWhenScrollable
|
||||||
|
{
|
||||||
|
get => showScrollBarOnlyWhenScrollable;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (showScrollBarOnlyWhenScrollable == value) return;
|
||||||
|
showScrollBarOnlyWhenScrollable = value;
|
||||||
|
RequestLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@ -333,13 +348,13 @@ namespace AlicizaX.UI
|
|||||||
scroller.Snap = snap;
|
scroller.Snap = snap;
|
||||||
scroller.OnValueChanged.AddListener(OnScrollChanged);
|
scroller.OnValueChanged.AddListener(OnScrollChanged);
|
||||||
scroller.OnMoveStoped.AddListener(OnMoveStoped);
|
scroller.OnMoveStoped.AddListener(OnMoveStoped);
|
||||||
|
UpdateScrollerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfigureScrollbar()
|
private void ConfigureScrollbar()
|
||||||
{
|
{
|
||||||
if (!showScrollBar || scrollbar == null) return;
|
if (!showScrollBar || scrollbar == null) return;
|
||||||
|
|
||||||
scrollbar.gameObject.SetActive(scroll);
|
|
||||||
scrollbar.onValueChanged.AddListener(OnScrollbarChanged);
|
scrollbar.onValueChanged.AddListener(OnScrollbarChanged);
|
||||||
|
|
||||||
var scrollbarEx = scrollbar.gameObject.GetComponent<ScrollbarEx>();
|
var scrollbarEx = scrollbar.gameObject.GetComponent<ScrollbarEx>();
|
||||||
@ -349,6 +364,7 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
scrollbarEx.OnDragEnd = OnScrollbarDragEnd;
|
scrollbarEx.OnDragEnd = OnScrollbarDragEnd;
|
||||||
|
UpdateScrollbarVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -428,15 +444,28 @@ namespace AlicizaX.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void RequestLayout()
|
public void RequestLayout()
|
||||||
{
|
{
|
||||||
|
if (layoutManager == null)
|
||||||
|
{
|
||||||
|
UpdateScrollbarVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
layoutManager.SetContentSize();
|
layoutManager.SetContentSize();
|
||||||
|
|
||||||
if (scroller == null) return;
|
if (scroller == null)
|
||||||
|
{
|
||||||
|
UpdateScrollbarVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scroller.Direction = direction;
|
scroller.Direction = direction;
|
||||||
scroller.ViewSize = layoutManager.ViewportSize;
|
scroller.ViewSize = layoutManager.ViewportSize;
|
||||||
scroller.ContentSize = layoutManager.ContentSize;
|
scroller.ContentSize = layoutManager.ContentSize;
|
||||||
|
scroller.Position = Mathf.Clamp(scroller.Position, 0, scroller.MaxPosition);
|
||||||
|
|
||||||
|
UpdateScrollerState();
|
||||||
UpdateScrollbarVisibility();
|
UpdateScrollbarVisibility();
|
||||||
|
UpdateScrollbarValue(scroller.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -661,11 +690,14 @@ namespace AlicizaX.UI
|
|||||||
|
|
||||||
private void UpdateScrollbarVisibility()
|
private void UpdateScrollbarVisibility()
|
||||||
{
|
{
|
||||||
if (scrollbar == null || scroller == null || layoutManager.ContentSize == Vector2.zero)
|
if (scrollbar == null)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool shouldShow = ShouldShowScrollbar();
|
bool shouldShow = ShouldShowScrollbar();
|
||||||
scrollbar.gameObject.SetActive(shouldShow);
|
scrollbar.gameObject.SetActive(shouldShow);
|
||||||
|
scrollbar.interactable = shouldShow;
|
||||||
|
|
||||||
if (shouldShow)
|
if (shouldShow)
|
||||||
{
|
{
|
||||||
@ -676,16 +708,22 @@ namespace AlicizaX.UI
|
|||||||
|
|
||||||
private bool ShouldShowScrollbar()
|
private bool ShouldShowScrollbar()
|
||||||
{
|
{
|
||||||
if (direction == Direction.Custom) return false;
|
if (!showScrollBar || !scroll || scrollbar == null || scroller == null || layoutManager == null || !SupportsOverflowCheck())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (direction == Direction.Vertical)
|
if (!HasValidScrollMetrics())
|
||||||
{
|
{
|
||||||
return layoutManager.ContentSize.y > layoutManager.ViewportSize.y;
|
return false;
|
||||||
}
|
}
|
||||||
else // Horizontal
|
|
||||||
|
if (!ShouldLimitScrollToOverflow())
|
||||||
{
|
{
|
||||||
return layoutManager.ContentSize.x > layoutManager.ViewportSize.x;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return HasScrollableContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfigureScrollbarDirection()
|
private void ConfigureScrollbarDirection()
|
||||||
@ -707,6 +745,61 @@ namespace AlicizaX.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateScrollerState()
|
||||||
|
{
|
||||||
|
if (scroller == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scroller.enabled = scroll && (!ShouldLimitScrollToOverflow() || HasScrollableContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldLimitScrollToOverflow()
|
||||||
|
{
|
||||||
|
return showScrollBar && showScrollBarOnlyWhenScrollable && SupportsOverflowCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasScrollableContent()
|
||||||
|
{
|
||||||
|
if (layoutManager == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == Direction.Vertical)
|
||||||
|
{
|
||||||
|
return layoutManager.ContentSize.y > layoutManager.ViewportSize.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == Direction.Horizontal)
|
||||||
|
{
|
||||||
|
return layoutManager.ContentSize.x > layoutManager.ViewportSize.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool SupportsOverflowCheck()
|
||||||
|
{
|
||||||
|
return direction == Direction.Vertical || direction == Direction.Horizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasValidScrollMetrics()
|
||||||
|
{
|
||||||
|
if (direction == Direction.Vertical)
|
||||||
|
{
|
||||||
|
return layoutManager.ContentSize.y > 0f && layoutManager.ViewportSize.y > 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == Direction.Horizontal)
|
||||||
|
{
|
||||||
|
return layoutManager.ContentSize.x > 0f && layoutManager.ViewportSize.x > 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void SnapToNearestItem()
|
private void SnapToNearestItem()
|
||||||
{
|
{
|
||||||
int index = layoutManager.PositionToIndex(GetScrollPosition());
|
int index = layoutManager.PositionToIndex(GetScrollPosition());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user