backup
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ba86d0ef2e4efd4290b2b4b7697aa85
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user