This commit is contained in:
2025-09-19 20:08:27 +08:00
parent a84e583dec
commit ea8058406c
12 changed files with 2370 additions and 155 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ namespace XericUI.Core.Vessel
/// </summary>
/// <typeparam name="T0"></typeparam>
[Serializable]
public class ObjectVessel<T0> : VesselBase
public sealed class ObjectVessel<T0> : VesselBase
where T0 : Object
{
[SerializeField]
+1 -1
View File
@@ -6,7 +6,7 @@ using Object = UnityEngine.Object;
namespace XericUI.Core.Vessel
{
[Serializable]
public class ObjectVessel<T0, T1> : VesselBase
public sealed class ObjectVessel<T0, T1> : VesselBase
where T0 : Object
where T1 : Object
{
+1 -1
View File
@@ -6,7 +6,7 @@ using Object = UnityEngine.Object;
namespace XericUI.Core.Vessel
{
[Serializable]
public class ObjectVessel<T0, T1, T2> : VesselBase
public sealed class ObjectVessel<T0, T1, T2> : VesselBase
where T0 : Object
where T1 : Object
where T2 : Object
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 73eb6a65472648ddafa15ed1a6f525a2
timeCreated: 1757990443
@@ -0,0 +1,322 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.Serialization;
using UnityEngine.UI;
using XericLibrary.Runtime.MacroLibrary;
using XericLibrary.Runtime.Type.SpatialAlgorithm;
using XericLibraryEditor.Debug;
using XericUI.Core.Base;
using XericUI.OverrideLayout;
#if ODIN_INSPECTOR
using Sirenix.OdinInspector;
#endif
namespace XericUI.DynamicActivitiesImpact
{
/// <summary>
/// 导入动态激活组件(需要外部控制部分检查与生命周期事件)
/// </summary>
[Obsolete("直接用XericScrollRect")]
public class UIDynamicActiveImpact : XericUIBehaciour
{
#region 字段属性
#if ODIN_INSPECTOR
[LabelText("主要容器")]
[BoxGroup("基本容器", centerLabel: true)]
#endif
[Tooltip("容器子集应呈现平摊的样式")]
public RectTransform containerTransform = null;
#if ODIN_INSPECTOR
[BoxGroup("基本容器")]
[LabelText("遮罩容器")]
#endif
[Tooltip("用作遮罩计算的组件")]
public RectTransform maskRectTransform = null;
#if ODIN_INSPECTOR
[BoxGroup("基本容器")]
[LabelText("容器排版控制")]
#endif
public LayoutGroup layoutGroup;
#if ODIN_INSPECTOR
[BoxGroup("容器性能")]
[LabelText("预加载像素范围")]
#endif
public float preloadMargin = 200f;
#if ODIN_INSPECTOR
[BoxGroup("容器性能")]
[LabelText("可被察觉的响应变化长度")]
#endif
public float discernibleDistance = 10f;
#if ODIN_INSPECTOR
[BoxGroup("容器性能")]
[LabelText("每秒检查更新的次数")]
#endif
[Range(0.1f, 50)]
public float updateRateLimit = 2;
#endregion
#region 容器成员
internal bool _layoutDirty;
internal bool _transformDirty;
internal int _lastChildrenCount;
internal Vector2 _lastPosition;
internal HashSet<RectTransform> _activeSet = null;
internal HashSet<RectTransform> _allObjsSet = null;
private HashSetPool<RectTransform> _tempQuadUIHashSetPool = new HashSetPool<RectTransform>();
/// <summary>
/// 保存所有ui对象的四叉树
/// </summary>
protected QuadTree<RectTransform> QuadUITargetTree;
public virtual IEnumerable<RectTransform> ContainerChildren => containerTransform.GetChildren().Select(a => a.RectTransform());
public virtual int ContainerChildrenCount => containerTransform.childCount;
public virtual Rect ContainerTransformRectRange => containerTransform.ToQuadTreeRect();
public virtual Rect MaskRectTransformRectRange => maskRectTransform.ToQuadTreeRect();
public bool IsLayoutDirty => _layoutDirty;
public bool IsTransformDirty => _transformDirty;
public float SaftyDiscernibleUpdateTime => Mathf.Max(1f / 60, 1f / updateRateLimit);
public LayoutGroup MainLayoutGroup => transform.GetComponent<LayoutGroup>();
#endregion
#region 生命周期
#if UNITY_EDITOR
private Vector3[] vertex1 = new Vector3[4];
private Vector3[] vertex2 = new Vector3[4];
private Vector3[] vertex3 = new Vector3[4];
private void OnDrawGizmosSelected()
{
var lossyScale = rectTransform.lossyScale;
var scale = lossyScale * preloadMargin;
var dis2 = lossyScale * discernibleDistance;
containerTransform.GetWorldCorners(vertex1);
vertex2[0] = new Vector3(vertex1[0].x - scale.x, vertex1[0].y - scale.y, vertex1[0].z);
vertex2[1] = new Vector3(vertex1[1].x - scale.x, vertex1[1].y + scale.y, vertex1[1].z);
vertex2[2] = new Vector3(vertex1[2].x + scale.x, vertex1[2].y + scale.y, vertex1[2].z);
vertex2[3] = new Vector3(vertex1[3].x + scale.x, vertex1[3].y - scale.y, vertex1[3].z);
vertex3[0] = new Vector3(vertex1[0].x - dis2.x, vertex1[0].y - dis2.y, vertex1[0].z);
vertex3[1] = new Vector3(vertex1[1].x - dis2.x, vertex1[1].y + dis2.y, vertex1[1].z);
vertex3[2] = new Vector3(vertex1[2].x + dis2.x, vertex1[2].y + dis2.y, vertex1[2].z);
vertex3[3] = new Vector3(vertex1[3].x + dis2.x, vertex1[3].y - dis2.y, vertex1[3].z);
Gizmos.color = Color.yellow;
MacroGizmosDraw.DrawPolygonLineByPointArray(vertex3);
MacroGizmosDraw.DrawGizmosRectLinkLine(vertex1, vertex2, Color.grey, Color.cyan, true);
}
#endif
protected override void Awake()
{
base.Awake();
// 容器
if (containerTransform == null)
containerTransform = rectTransform;
// 遮罩
if (maskRectTransform == null)
{
var mask = transform.GetComponentInParent<Mask>();
maskRectTransform = mask.RectTransform();
}
// 布局
if (layoutGroup == null)
layoutGroup = transform.GetComponentInParent<LayoutGroup>();
if (layoutGroup is XericHorizontalOrVerticalLayoutGroup xericLayoutGroup)
{
xericLayoutGroup.layoutIgnoreInactive = false;
}
CheckIsDirty();
}
protected override void OnEnable()
{
base.OnEnable();
}
protected override void OnDisable()
{
base.OnDisable();
}
private float accTime = 0;
protected virtual void Update()
{
if (accTime < SaftyDiscernibleUpdateTime)
{
accTime += Time.unscaledDeltaTime;
return;
}
// 毕竟这里不是粒子计算器
accTime = accTime % SaftyDiscernibleUpdateTime;
if (IsLayoutDirty)
{
ResetDirtyFlag();
RebuildQurdTree();
}
else if (IsTransformDirty)
{
ResetDirtyFlag();
}
}
protected override void OnRectTransformDimensionsChange()
{
base.OnRectTransformDimensionsChange();
CheckIsDirty();
}
private void OnDestroy()
{
// 恢复所有元素的原始状态
foreach (var element in _allObjsSet)
{
if (element != null && _activeSet.Contains(element))
{
element.gameObject.SetActive(true);
}
}
}
#endregion
#region 刷新框架
/// <summary>
/// 设置布局脏
/// </summary>
public void LayoutDirty()
=> _layoutDirty = true;
/// <summary>
/// 设置变换脏
/// </summary>
public void TransformDirty()
=> _transformDirty = true;
/// <summary>
/// 重置脏标记
/// </summary>
private void ResetDirtyFlag()
{
_layoutDirty = false;
_transformDirty = false;
}
/// <summary>
/// 检查容器脏
/// </summary>
public virtual void CheckIsDirty()
{
if (QuadUITargetTree == null || // 四叉树不存在?
_lastChildrenCount != ContainerChildrenCount // 成员数量明显不对
)
{
LayoutDirty();
BackupQuadRectValue();
return;
}
// todo 这里暂时只简单考虑直来直去的移动方式,如果有其他复杂移动,需要修改判别条件
var deltaPosIsDirty = Mathf.Abs(QuadUITargetTree.RootRect.position.sqrMagnitude - _lastPosition.sqrMagnitude) < discernibleDistance;
if (deltaPosIsDirty // 发生不可忽视的变换?
)
{
TransformDirty();
BackupQuadRectValue();
return;
}
}
/// <summary>
/// 重建四叉树
/// </summary>
public void RebuildQurdTree()
{
// 重建四叉树
QuadUITargetTree = new QuadTree<RectTransform>(ContainerTransformRectRange, a => a.rect);
// 记录参数
BackupQuadRectValue();
}
/// <summary>
/// 保存自动重建四叉树所需的参数
/// </summary>
/// <param name="target"></param>
protected virtual void BackupQuadRectValue()
{
_lastPosition = ContainerTransformRectRange.position;
_lastChildrenCount = ContainerChildrenCount;
}
#if ODIN_INSPECTOR
[Button("更新所有可见性")]
#endif
/// <summary>
/// 更新所有成员的可见性
/// </summary>
public virtual void UpdateAllObjectVisible()
{
if (QuadUITargetTree == null)
{
Debug.LogError($"在更新成员可见性之前,需要确保四叉树存在!");
return;
}
var visibalSet = QuadUITargetTree.Retrieve(MaskRectTransformRectRange);
ContainerChildren.ForEachDo(obj =>
{
obj.gameObject.SetActive(visibalSet.Contains(obj));
});
}
/// <summary>
/// 要求控制布局组的激活一次,提供为何激活的原因
/// </summary>
/// <param name="hasIncreased">由于新增成员导致布局更新</param>
/// <param name="hasDecreased">由于销毁成员导致布局更新</param>
public virtual void UpdateLayoutGroupOnce(bool hasIncreased, bool hasDecreased)
{
MainLayoutGroup.enabled = true;
StartCoroutine(WaitForLayoutDisable());
return;
IEnumerator WaitForLayoutDisable()
{
if (CanvasUpdateRegistry.IsRebuildingLayout())
yield return new WaitForEndOfFrame();
else
yield return new WaitForFixedUpdate();
MainLayoutGroup.enabled = false;
}
}
#endregion
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 48016863e20f4c61a91245c593d575da
timeCreated: 1757990480
+10 -6
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Deconstruction.Runtime.UI;
using JetBrains.Annotations;
using Sirenix.OdinInspector;
@@ -164,6 +165,8 @@ namespace XericUI.FlipPage
#endif
[CanBeNull]
internal ObjectVessel<Selectable, TMPro.TMP_Text> pageSelectableVessel;
protected internal override void OnPageVisible(bool quickVisit)
{
@@ -184,7 +187,7 @@ namespace XericUI.FlipPage
protected internal override void OnPageInvisible(bool quickVisit)
{
}
}
/// <summary>
@@ -303,6 +306,8 @@ namespace XericUI.FlipPage
return result;
}
public override void RemovePage(int pageIndex)
{
base.RemovePage(pageIndex);
@@ -316,11 +321,10 @@ namespace XericUI.FlipPage
public override void ClearPages()
{
foreach (var pageInfo in PageInfos)
{
var page = pageInfo as PageComponentInfo;
pageButtonPool.DirectlyRelease(page.pageSelectableVessel.Target0.gameObject);
}
PageInfos
.OfType<PageComponentInfo>()
.Where(a => a.pageSelectableVessel.IsValidVessel())
.ForEachDo(a => pageButtonPool.DirectlyRelease(a.pageSelectableVessel!.Target0.gameObject));
pageSelectButton.Clear();
base.ClearPages();
RefreshLabelTextTotalPageCount();
+46
View File
@@ -0,0 +1,46 @@
using System;
using UnityEngine;
using UnityEngine.Pool;
namespace XericUI.FlipPage
{
/// <summary>
/// 翻页组件管理器(通用数据层)
/// </summary>
[AddComponentMenu("Xeric UI Vessel/FlipPage/General FilpPage Manager")]
public class GeneralDataFlipPage : FlipPageComponentManager
{
#region 生命周期
protected override void Awake()
{
base.Awake();
}
#endregion
#region 容器控制
/// <summary>
/// 添加一个数据项目
/// </summary>
/// <param name="item">数据项目</param>
/// <typeparam name="T"></typeparam>
public void AddItem<T>(T item)
where T : ItemComponentInfo
{
base.AddItem(item, () => AddPageLast(new PageComponentInfo()));
}
/// <summary>
/// 添加一个数据项目
/// </summary>
/// <param name="item">数据项目</param>
public override void AddItem(ItemInfo item)
{
base.AddItem(item, () => AddPageLast(new PageComponentInfo()));
}
#endregion
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b51ce3649dd74e438a0d79a2935a866f
timeCreated: 1758195174
+239 -146
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.Serialization;
using UnityEngine.UI;
using XericLibrary.Runtime.MacroLibrary;
@@ -67,136 +68,6 @@ namespace XericUI.FlipPage
#endregion
#region 类内类型
/// <summary>
/// 页面信息
/// </summary>
[Serializable]
public abstract class PageInfo
{
#region 字段属性
/// <summary>
/// 页面名称
/// </summary>
#if ODIN_INSPECTOR
[LabelText("页面名称")]
#endif
public string name = DateTime.Now.Ticks.ToString();
/// <summary>
/// 页面内项目列表
/// </summary>
#if ODIN_INSPECTOR
[LabelText("页面项目信息")]
#endif
public List<ItemInfo> itemInfos = new List<ItemInfo>();
/// <summary>
/// 从零开始计数的页面下标
/// </summary>
#if ODIN_INSPECTOR
[LabelText("页面索引[0, n]")]
#endif
public int pageNumber { get; internal set; }
#endregion
#region 生命周期
/// <summary>
/// 页面创建时
/// </summary>
protected internal virtual void OnPageCreated(XericFlipPageIndexVesselBase parent)
{
}
/// <summary>
/// 页面销毁时
/// </summary>
protected internal virtual void OnPageDestroy(XericFlipPageIndexVesselBase parent)
{
}
/// <summary>
/// 页面显示时
/// </summary>
/// <param name="quickVisit">快速浏览(用于区分动画和逻辑,为真时,不应当在动画事件后继续加载数据)</param>
protected internal abstract void OnPageVisible(bool quickVisit);
/// <summary>
/// 页面隐藏时
/// </summary>
/// <param name="quickVisit">快速浏览(用于区分动画和逻辑,为真时,不应当在动画事件后继续加载数据)</param>
protected internal abstract void OnPageInvisible(bool quickVisit);
#endregion
public override string ToString()
{
return $"[{nameof(PageInfo)}] ({name})";
}
}
/// <summary>
/// 项目信息
/// </summary>
[Serializable]
public abstract class ItemInfo
{
#region 字段属性
#if ODIN_INSPECTOR
[LabelText("项目名称")]
#endif
public string name = DateTime.Now.Ticks.ToString();
/// <summary>
/// 从零开始计数的项目下标
/// </summary>
#if ODIN_INSPECTOR
[LabelText("项目索引[0, n]")]
#endif
public int itemNumber { get; internal set; }
#endregion
#region 生命周期
/// <summary>
/// 当项目显示时
/// </summary>
protected internal abstract void OnItemVisible();
/// <summary>
/// 当项目隐藏时
/// </summary>
protected internal abstract void OnItemInvisible();
#endregion
/// <summary>
/// 是否通过过滤器
/// </summary>
/// <param name="manager">传入管理器,建议将过滤器放在管理器中,然后具体的通过规则写在这里,根据对象的不同,通过的规则都不一样。</param>
/// <returns></returns>
public virtual bool PassFilter(XericFlipPageIndexVesselBase manager)
{
return true;
}
public override string ToString()
{
return $"[{nameof(ItemInfo)}] ({name})";
}
}
#endregion
#region 字段属性
/// <summary>
@@ -219,12 +90,12 @@ namespace XericUI.FlipPage
/// 所有页面
/// </summary>
private LinkedList<PageInfo> _pageInfos = new LinkedList<PageInfo>();
private readonly LinkedList<PageInfo> _pageInfos = new LinkedList<PageInfo>();
/// <summary>
/// 所有列表项目
/// </summary>
private HashSet<ItemInfo> _itemInfos = new HashSet<ItemInfo>();
private readonly HashSet<ItemInfo> _itemInfos = HashSetPool<ItemInfo>.Get();
/// <summary>
@@ -272,18 +143,18 @@ namespace XericUI.FlipPage
#region 生命周期
protected override void Awake()
{
base.Awake();
}
protected override void Start()
{
base.Start();
FlipPage(currentPageIndex);
}
protected override void OnDestroy()
{
base.OnDestroy();
HashSetPool<ItemInfo>.Release(_itemInfos);
}
#endregion
#region 翻页管理
@@ -335,6 +206,8 @@ namespace XericUI.FlipPage
// 如果索引偏移,逐个移动
else if (pageIndexOffset > 0)
{
// 先关闭页面元素
CurrentPageNode.Value.CallChildItemInvisible();
for (var i = 0; i < pageIndexOffset; i++)
{
var next = CurrentPageNode!.Next;
@@ -343,16 +216,22 @@ namespace XericUI.FlipPage
}
else if (pageIndexOffset < 0)
{
// 先关闭页面元素
CurrentPageNode.Value.CallChildItemInvisible();
for (var i = 0; i > pageIndexOffset; i--)
{
var previa = CurrentPageNode!.Previous;
SwitchPage(previa, _pageInfos.First, i - 1 > pageIndexOffset);
}
}
// 没有翻动有效页,退出
// 没有翻动有效页,直接退出
else
return;
// 可能时当前不存在任何页面
if (CurrentPageNode == null)
return;
// 页面元素激活
CurrentPageNode.Value.CallChildItemVisible();
currentPageIndex = pageIndex;
OnFlipPage();
@@ -411,6 +290,8 @@ namespace XericUI.FlipPage
public void FlipPageToEnd()
=> FlipPage(_pageInfos.Count - 1);
/// <summary>
/// 添加页面在开头
/// </summary>
@@ -449,12 +330,34 @@ namespace XericUI.FlipPage
// 添加页面
_pageInfos.AddLast(pageInfo);
// 执行页面生命周期
pageInfo.OnPageDestroy(this);
pageInfo.OnPageCreated(this);
// 刷新页面
FlipPage(currentPageIndex, true);
return pageInfo;
}
/// <summary>
/// 按对象引用删除页面
/// </summary>
/// <param name="pageInfo"></param>
public virtual void RemovePage(PageInfo pageInfo)
{
// 如果移除的是当前页面,执行关闭操作
if (CurrentPageNode.Value == pageInfo)
{
pageInfo.OnPageInvisible(true);
CurrentPageNode = null;
}
// 执行页面生命周期
pageInfo.OnPageDestroy(this);
// 页面索引移除
_pageInfos.Remove(pageInfo);
// 刷新页面
FlipPage(currentPageIndex, true);
var index = PageInfos.IndexOf(a => a == pageInfo);
RemovePage(index);
}
/// <summary>
/// 移除页面(页面上的数据内容也会一同移除)
/// </summary>
@@ -508,7 +411,16 @@ namespace XericUI.FlipPage
/// <returns></returns>
public T IndexOfPageInfo<T>(int pageIndex)
where T : PageInfo
=> _pageInfos.LandedIndex(pageIndex) as T;
=> IndexOfPageInfo(pageIndex) as T;
/// <summary>
/// 获取索引下的页面
/// </summary>
/// <param name="pageIndex"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public PageInfo IndexOfPageInfo(int pageIndex)
=> _pageInfos.LandedIndex(pageIndex);
/// <summary>
/// 清除所有页面 (所有页面数据也会一同移除)
@@ -567,7 +479,7 @@ namespace XericUI.FlipPage
/// <summary>
/// 添加数据项目
/// </summary>
public void AddItem(ItemInfo item, Func<PageInfo> addPage)
public virtual void AddItem(ItemInfo item, Func<PageInfo> addPage)
{
// 向前寻找空缺(这在页面都被准确填充的情况下最忧)
var firstVacancy = _pageInfos
@@ -577,22 +489,24 @@ namespace XericUI.FlipPage
if (firstVacancy != null)
{
firstVacancy.Value.itemInfos.Add(item);
_itemInfos.Add(item);
return;
}
if (addPage == null)
{
Debug.LogError("当前页面已满,数据项目顺位添加到新页面中,但未指定页面创建函数,添加过程已退出", this);
Debug.LogError("当前页面已满,数据项目期望顺位添加到新页面中,但未指定页面创建函数,添加过程已退出", this);
return;
}
// 新建一个页面存放数据
addPage.Invoke().itemInfos.Add(item);
_itemInfos.Add(item);
}
/// <summary>
/// 移除所有包含给定项目的位置(这会在页面上留下空缺)
/// </summary>
/// <param name="item"></param>
public void RemoveItem(ItemInfo item)
public virtual void RemoveItem(ItemInfo item)
{
foreach (var a in AllItemInfos
.Adjoint()
@@ -600,10 +514,11 @@ namespace XericUI.FlipPage
.Reverse())
{
ItemIndex2PageIndex(a.index);
}
}
public void RemoveItem(int indexItem)
public virtual void RemoveItem(int indexItem)
{
}
@@ -641,6 +556,15 @@ namespace XericUI.FlipPage
{
return itemIndex / DefaultItemCountPerPage;
}
/// <summary>
/// 当前翻页管理器中包含给定数据项目
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Contains(ItemInfo item)
=> _itemInfos.Contains(item);
/// <summary>
/// 获取备份所有数据项目
@@ -723,5 +647,174 @@ namespace XericUI.FlipPage
#endregion
#region 类内类型
/// <summary>
/// 页面信息
/// </summary>
[Serializable]
public abstract class PageInfo
{
#region 字段属性
/// <summary>
/// 页面名称
/// </summary>
#if ODIN_INSPECTOR
[LabelText("页面名称")]
#endif
public string name = DateTime.Now.Ticks.ToString();
/// <summary>
/// 页面内项目列表
/// </summary>
#if ODIN_INSPECTOR
[LabelText("页面项目信息")]
#endif
public List<ItemInfo> itemInfos;
/// <summary>
/// 从零开始计数的页面下标
/// </summary>
#if ODIN_INSPECTOR
[LabelText("页面索引[0, n]")]
#endif
public int pageNumber { get; internal set; }
#endregion
#region 生命周期
/// <summary>
/// 页面创建时
/// </summary>
protected internal virtual void OnPageCreated(XericFlipPageIndexVesselBase parent)
{
// 获取列表
itemInfos = ListPool<ItemInfo>.Get();
}
/// <summary>
/// 页面销毁时
/// </summary>
protected internal virtual void OnPageDestroy(XericFlipPageIndexVesselBase parent)
{
// 从哈希表中移除
foreach (var itemInfo in itemInfos)
parent._itemInfos.Remove(itemInfo);
// 释放列表
if (itemInfos != null)
ListPool<ItemInfo>.Release(itemInfos);
}
/// <summary>
/// 页面显示时
/// </summary>
/// <param name="quickVisit">快速浏览(用于区分动画和逻辑,为真时,不应当在动画事件后继续加载数据)</param>
/// <code>
/// 页面中的成员会自动在非快速浏览模式下自动执行相应的激活函数
/// </code>
protected internal abstract void OnPageVisible(bool quickVisit);
/// <summary>
/// 页面隐藏时
/// </summary>
/// <param name="quickVisit">快速浏览(用于区分动画和逻辑,为真时,不应当在动画事件后继续加载数据)</param>
/// <code>
/// 页面中的成员会自动在非快速浏览模式下自动执行相应的激活函数
/// </code>
protected internal abstract void OnPageInvisible(bool quickVisit);
#endregion
/// <summary>
/// 传递子项激活回调事件
/// </summary>
protected internal virtual void CallChildItemVisible()
{
itemInfos
.Where(a => a != null)
.ForEachDo(itemInfo => itemInfo.OnItemVisible());
}
/// <summary>
/// 传递子项非激活回调事件
/// </summary>
protected internal virtual void CallChildItemInvisible()
{
itemInfos
.Where(a => a != null)
.ForEachDo(itemInfo => itemInfo.OnItemInvisible());
}
public override string ToString()
{
return $"[{nameof(PageInfo)}] ({name})";
}
}
/// <summary>
/// 项目信息
/// </summary>
[Serializable]
public abstract class ItemInfo
{
#region 字段属性
#if ODIN_INSPECTOR
[LabelText("项目名称")]
#endif
public string name = DateTime.Now.Ticks.ToString();
/// <summary>
/// 从零开始计数的项目下标
/// </summary>
#if ODIN_INSPECTOR
[LabelText("项目索引[0, n]")]
#endif
public int itemNumber { get; internal set; }
#endregion
#region 生命周期
/// <summary>
/// 当项目显示时
/// </summary>
/// <code>
/// 这会在页面显示之后执行
/// </code>
protected internal abstract void OnItemVisible();
/// <summary>
/// 当项目隐藏时
/// </summary>
/// <code>
/// 这会在页面关闭之前执行
/// </code>
protected internal abstract void OnItemInvisible();
#endregion
/// <summary>
/// 是否通过过滤器
/// </summary>
/// <param name="manager">传入管理器,建议将过滤器放在管理器中,然后具体的通过规则写在这里,根据对象的不同,通过的规则都不一样。</param>
/// <returns></returns>
public virtual bool PassFilter(XericFlipPageIndexVesselBase manager)
{
return true;
}
public override string ToString()
{
return $"[{nameof(ItemInfo)}] ({name})";
}
}
#endregion
}
}
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5ba86d0ef2e4efd4290b2b4b7697aa85
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: