diff --git a/Editor/OverrideUI/XericToggleEditor.cs b/Editor/OverrideUI/XericToggleEditor.cs
index 08e9fd0..35e0a77 100644
--- a/Editor/OverrideUI/XericToggleEditor.cs
+++ b/Editor/OverrideUI/XericToggleEditor.cs
@@ -18,9 +18,11 @@ namespace XericUIEditor.OverrideUI
SerializedProperty m_TextProperty;
SerializedProperty m_EnableTextColorTransitionProperty;
+ SerializedProperty m_isonStatusColor;
SerializedProperty m_TextTransitionColorModeProperty;
SerializedProperty m_enableTextContextTransitionProperty;
SerializedProperty m_textTransitionContextModeProperty;
+ SerializedProperty m_isonStatusTextContext;
protected override void OnEnable()
{
@@ -34,9 +36,11 @@ namespace XericUIEditor.OverrideUI
m_TextProperty = serializedObject.FindProperty("m_text");
m_EnableTextColorTransitionProperty = serializedObject.FindProperty("m_enableTextColorTransition");
+ m_isonStatusColor = serializedObject.FindProperty("m_isonStatusColor");
m_TextTransitionColorModeProperty = serializedObject.FindProperty("m_textTransitionColorMode");
m_enableTextContextTransitionProperty = serializedObject.FindProperty("m_enableTextContextTransition");
m_textTransitionContextModeProperty = serializedObject.FindProperty("m_textTransitionContextMode");
+ m_isonStatusTextContext = serializedObject.FindProperty("m_isonStatusTextContext");
}
public override void OnInspectorGUI()
@@ -76,6 +80,7 @@ namespace XericUIEditor.OverrideUI
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_TextTransitionColorModeProperty);
+ EditorGUILayout.PropertyField(m_isonStatusColor);
EditorGUI.indentLevel--;
}
EditorGUILayout.PropertyField(m_enableTextContextTransitionProperty);
@@ -83,6 +88,7 @@ namespace XericUIEditor.OverrideUI
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_textTransitionContextModeProperty);
+ EditorGUILayout.PropertyField(m_isonStatusTextContext);
EditorGUI.indentLevel--;
}
diff --git a/Runtime/OverrideLayout/XericScrollRect.cs b/Runtime/OverrideLayout/XericScrollRect.cs
index a75c819..4228461 100644
--- a/Runtime/OverrideLayout/XericScrollRect.cs
+++ b/Runtime/OverrideLayout/XericScrollRect.cs
@@ -56,7 +56,7 @@ namespace XericUI.OverrideLayout
///
/// 对象数据
///
- [SerializeField] private readonly List _childrenDatas = ListPool.Get();
+ [SerializeField] private readonly List _childrenDatas = new List();
public Vector2 ContextSize
{
@@ -83,6 +83,7 @@ namespace XericUI.OverrideLayout
private Queue _activeQueue = new Queue();
+ private bool layoutHasRebuildAtThisFrame;
private bool layoutDirty;
private bool indexMapDirty;
@@ -97,20 +98,21 @@ namespace XericUI.OverrideLayout
private bool _uiVisibal;
protected GameObject item;
-
+ public RectTransform itemRectTransform => item ? item.RectTransform() : null;
+ public IUIVesselVisibalControl ItemUIVesselVisibalControlComponent => item ? itemRectTransform.GetComponent() : null;
public bool GetUIVisibal => _uiVisibal;
public virtual void UnderVisibal()
{
item = parentScrollRect.childrenPool.Get();
- var rectTransform = item.RectTransform();
parentScrollRect.UpdateChildPivot(layout, item.RectTransform());
- rectTransform.anchoredPosition = layout.position;
+ itemRectTransform.anchoredPosition = layout.position;
}
public virtual void OutOfVisibal()
{
parentScrollRect.childrenPool.DirectlyRelease(item);
+ item = null;
}
public void UpdateLayout(GridLayoutCalculator.LayoutItem layoutData)
@@ -211,18 +213,22 @@ namespace XericUI.OverrideLayout
{
// 只有距离大于这个才会触发更新
_lastContextAnchoredPosition = position;
- UpdateAAMVSVisibleStatus(position);
+ UpdateAAMVSVisibleStatus();
}
}
}
protected override void LateUpdate()
{
+ layoutHasRebuildAtThisFrame = false;
base.LateUpdate();
// 布局刷新
if (layoutDirty)
{
layoutDirty = false;
+ // 常规的刷新依赖视图的更新,如果这一帧只增删了对象,但是视图没有移动,那么这里就会执行更新
+ if (layoutHasRebuildAtThisFrame)
+ UpdateAAMVSVisibleStatus();
RefreshLayout();
}
// 全部索引刷新
@@ -239,8 +245,9 @@ namespace XericUI.OverrideLayout
///
/// 自动剔除更新标记
///
- protected void UpdateAAMVSVisibleStatus(Vector2 position)
+ protected void UpdateAAMVSVisibleStatus()
{
+ layoutHasRebuildAtThisFrame = true;
// 将视口尺寸转换到content本地空间
// 手动计算视口在content空间的矩形
viewport.GetWorldCorners(viewportVertex);
@@ -261,57 +268,68 @@ namespace XericUI.OverrideLayout
// horizontal ? horizontalScrollbar?.value ?? 0 : 0,
// vertical ? 1 - (verticalScrollbar?.value ?? 1) : 0);
- // ReSharper disable once PossibleInvalidCastExceptionInForeachLoop
- foreach (RectTransform child in content.GetChildren())
+ foreach (var childData in _childrenDatas)
{
- var visControl = child.GetComponent();
- var isVisControlValid = visControl != null;
+ var childRectTransform = childData.itemRectTransform;
+ if (childRectTransform)
+ {
+ var visControl = childData.ItemUIVesselVisibalControlComponent;
+ var isVisControlValid = visControl != null;
+
+ // 直接使用anchoredPosition进行边界检测
+ var childPos = childRectTransform.anchoredPosition;
+ var isVisible = CheckIsVisibal(childPos);
+ var nowActive = childRectTransform.GetActivity();
- var rectTransform = child.RectTransform();
- // 直接使用anchoredPosition进行边界检测
- var childPos = rectTransform.anchoredPosition;
- var isVisible =
- childPos.x >= visibleMin.x &&
- childPos.x <= visibleMax.x &&
- childPos.y >= visibleMin.y &&
- childPos.y <= visibleMax.y;
+ // 以接口为准
+ if (isVisControlValid)
+ nowActive = visControl.GetUIVisibal;
- var nowActive = child.GetActivity();
+ // 现在的状态与实际一致,跳过
+ if (isVisible == nowActive)
+ continue;
- // 以接口为准
- if (isVisControlValid)
- nowActive = visControl.GetUIVisibal;
-
- // 现在的状态与实际一致,跳过
- if (isVisible == nowActive)
- continue;
-
- // 向成员发送状态(如果成员没有实现接口,就直接通过可见性控制)
- if (isVisControlValid)
- visControl.CallVisibal(isVisible);
+ // 向成员发送状态(如果成员没有实现接口,就直接通过可见性控制)
+ if (isVisControlValid)
+ visControl.CallVisibal(isVisible);
+ else
+ childRectTransform.gameObject.SetActive(isVisible);
+ }
else
- child.gameObject.SetActive(isVisible);
+ {
+ var isVisible = CheckIsVisibal(childData.layout.position);
+ if (isVisible)
+ {
+ childData.UnderVisibal();
+ }
+ }
+ }
+
+ bool CheckIsVisibal(Vector2 pos)
+ {
+ return
+ pos.x >= visibleMin.x &&
+ pos.x <= visibleMax.x &&
+ pos.y >= visibleMin.y &&
+ pos.y <= visibleMax.y;
}
}
+
+
#endregion
#region 数据管理
- public T GetScrollItemData()
- where T : ScrollItemData, new()
- {
- var result = new T
- {
- parentScrollRect = this
- };
- return result;
- }
-
+ ///
+ /// 添加一个子项(自行重写这个子项类型数据结构,基于其中的生命周期函数完成内容的更新)
+ ///
+ ///
public void AddChildData(ScrollItemData Data)
{
layoutDirty = true;
Data.index = _childrenDatas.Count;
+ Data.parentScrollRect = this;
_childrenDatas.Add(Data);
}
diff --git a/Runtime/OverrideUI/XericImage.cs b/Runtime/OverrideUI/XericImage.cs
new file mode 100644
index 0000000..51e9a47
--- /dev/null
+++ b/Runtime/OverrideUI/XericImage.cs
@@ -0,0 +1,59 @@
+using System;
+using UnityEngine;
+using UnityEngine.Serialization;
+using UnityEngine.UI;
+using XericUI.Helper;
+
+namespace XericUI.OverrideUI
+{
+ ///
+ /// 图像组件
+ ///
+ ///
+ /// 这个组件主要为了提供graphic层的事件,用于应对部分无法重写的ui组件事件
+ ///
+ public class XericImage : Image
+ {
+ ///
+ /// 针对toggle的回报(ison)
+ ///
+ internal Action OnToggleCrossFadeCall;
+ public override void CrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha, bool useRGB)
+ {
+ base.CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha, useRGB);
+ OnToggleCrossFadeCall?.Invoke(targetColor.a > 0);
+ }
+
+ #region 组件替换
+#if UNITY_EDITOR
+ [UnityEditor.MenuItem("CONTEXT/Image/Replace To XericImage", true)]
+ private static bool ValidateReplaceToXeric(UnityEditor.MenuCommand command)
+ => command.context is Image and not XericImage;
+
+ [UnityEditor.MenuItem("CONTEXT/Image/Replace To XericImage", false, 10)]
+ private static void ReplaceToXeric(UnityEditor.MenuCommand command)
+ => command.ReplaceCommandContext(
+ o =>
+ o.sprite,
+ (t, d) =>
+ {
+ t.sprite = d;
+ });
+
+ [UnityEditor.MenuItem("CONTEXT/Image/Replace To Image", true)]
+ private static bool ValidateReplaceToUnity(UnityEditor.MenuCommand command)
+ => command.context is XericImage;
+
+ [UnityEditor.MenuItem("CONTEXT/Image/Replace To Image", false, 10)]
+ private static void ReplaceToUnity(UnityEditor.MenuCommand command)
+ => command.ReplaceCommandContext(
+ o =>
+ o.sprite,
+ (t, d) =>
+ {
+ t.sprite = d;
+ });
+#endif
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Runtime/OverrideUI/XericImage.cs.meta b/Runtime/OverrideUI/XericImage.cs.meta
new file mode 100644
index 0000000..c7e2db0
--- /dev/null
+++ b/Runtime/OverrideUI/XericImage.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 52aeb4e8bd3a4b6c9513b8ad21b41558
+timeCreated: 1776850195
\ No newline at end of file
diff --git a/Runtime/OverrideUI/XericToggle.cs b/Runtime/OverrideUI/XericToggle.cs
index 9fbcb84..4bff171 100644
--- a/Runtime/OverrideUI/XericToggle.cs
+++ b/Runtime/OverrideUI/XericToggle.cs
@@ -6,6 +6,7 @@ using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
using XericUI.Helper;
+using XericUI.OverrideUI;
namespace XericUI
{
@@ -46,6 +47,7 @@ namespace XericUI
public bool m_enableTextColorTransition = true;
public ColorBlock m_textTransitionColorMode = ColorBlock.defaultColorBlock;
+ public Color m_isonStatusColor = Color.white;
public bool m_enableTextContextTransition = false;
public AnimationTriggers m_textTransitionContextMode = new AnimationTriggers()
{
@@ -55,6 +57,9 @@ namespace XericUI
selectedTrigger = "toggle_selected",
disabledTrigger = "toggle_disabled",
};
+
+ public string m_isonStatusTextContext = "toggle_ison";
+
public bool EnableTextColorTransition
{
@@ -67,7 +72,39 @@ namespace XericUI
get => m_textTransitionColorMode;
set => m_textTransitionColorMode = value;
}
-
+
+
+ private XericImage m_ximage;
+
+ protected XericImage ximage
+ {
+ get
+ {
+ if (m_ximage)
+ return m_ximage;
+#if UNITY_EDITOR
+ if (!graphic)
+ return null;
+#endif
+ m_ximage = graphic.GetComponent();
+ if (m_ximage)
+ return m_ximage;
+ Debug.Log("עÒâÌ滻toggleµÄcheckmarkΪXericImageÒÔ֧³ÖÍêÕûµĹ¦ÄÜ");
+ return null;
+ }
+ }
+
+ private bool bindXImage;
+
+ protected override void InstantClearState()
+ {
+ base.InstantClearState();
+
+ if (m_enableTextColorTransition)
+ TextColor = colors.normalColor;
+ if (m_enableTextContextTransition)
+ TextContent = m_textTransitionContextMode.normalTrigger;
+ }
protected override void DoStateTransition(SelectionState state, bool instant)
{
if (!gameObject.activeInHierarchy)
@@ -117,8 +154,8 @@ namespace XericUI
transitionName = m_textTransitionContextMode.disabledTrigger;
break;
default:
- tintColor = Color.black;
- textColor = Color.white;
+ tintColor = colors.normalColor;
+ textColor = m_textTransitionColorMode.normalColor;
transitionSprite = null;
triggerName = string.Empty;
transitionName = m_textTransitionContextMode.normalTrigger;
@@ -138,13 +175,25 @@ namespace XericUI
break;
}
+ if (!bindXImage && ximage != null)
+ {
+ bindXImage = true;
+ ximage.OnToggleCrossFadeCall = b =>
+ {
+ if (m_enableTextColorTransition)
+ TextColor = b ? m_textTransitionColorMode.pressedColor : m_textTransitionColorMode.normalColor;
+ if (m_enableTextContextTransition)
+ TextContent = b ? m_textTransitionContextMode.pressedTrigger : m_textTransitionContextMode.normalTrigger;
+ };
+ }
+
+
if (m_enableTextColorTransition)
- TextColor = isOn ? m_textTransitionColorMode.selectedColor : textColor;
+ TextColor = isOn ? m_isonStatusColor : textColor;
if (m_enableTextContextTransition)
TextContent = transitionName;
}
-
-
+
void StartColorTween(Color targetColor, bool instant)
{
if (targetGraphic == null)
@@ -184,8 +233,9 @@ namespace XericUI
=> command.context is Toggle and not XericToggle;
[UnityEditor.MenuItem("CONTEXT/Toggle/Replace To XericToggle", false, 10)]
- private static void ReplaceToXeric(UnityEditor.MenuCommand command)
- => command.ReplaceCommandContext(
o =>
(o.graphic, o.group, o.onValueChanged),
@@ -195,6 +245,8 @@ namespace XericUI
t.group = d.group;
t.onValueChanged = d.onValueChanged;
});
+ Debug.Log("ÇëÊֶ¯Ì滻toggleϵÄCheckmark Image×é¼þΪXericImage£¬·ñÔòToggle¹¤×÷ʱȡÏûѡÔñµÄ״̬»ᱣ³ÖΪison״̬¡£");
+ }
[UnityEditor.MenuItem("CONTEXT/Toggle/Replace To Toggle", true)]
private static bool ValidateReplaceToUnity(UnityEditor.MenuCommand command)
@@ -214,5 +266,6 @@ namespace XericUI
});
#endif
#endregion
+
}
}