完成翻页管理器
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using Deconstruction.Runtime.UI;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Sirenix.OdinInspector;
|
using Sirenix.OdinInspector;
|
||||||
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using XericLibrary.Runtime.MacroLibrary;
|
using XericLibrary.Runtime.MacroLibrary;
|
||||||
@@ -120,7 +122,19 @@ namespace XericUI.FlipPage
|
|||||||
|
|
||||||
#region 字段属性
|
#region 字段属性
|
||||||
|
|
||||||
protected ToggleGroup ToggleGroup;
|
|
||||||
|
private ToggleGroup _toggleGroup;
|
||||||
|
|
||||||
|
protected ToggleGroup ToggleGroup
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_toggleGroup != null)
|
||||||
|
return _toggleGroup;
|
||||||
|
_toggleGroup = transform.GetComponentAnyway<ToggleGroup>();
|
||||||
|
return _toggleGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -138,7 +152,7 @@ namespace XericUI.FlipPage
|
|||||||
[LabelText("页面翻页按钮")]
|
[LabelText("页面翻页按钮")]
|
||||||
#endif
|
#endif
|
||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
internal ObjectVessel<Selectable, TMPro.TMP_Text> pageIndexSelectable;
|
internal ObjectVessel<Selectable, TMPro.TMP_Text> pageSelectableVessel;
|
||||||
|
|
||||||
protected internal override void OnPageVisible(bool quickVisit)
|
protected internal override void OnPageVisible(bool quickVisit)
|
||||||
{
|
{
|
||||||
@@ -146,18 +160,20 @@ namespace XericUI.FlipPage
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// 自动补全外部交互动画
|
// 自动补全外部交互动画
|
||||||
if (pageIndexSelectable.IsValidVessel() &&
|
if (pageSelectableVessel.IsValidVessel())
|
||||||
pageIndexSelectable.Target0 is Toggle toggle &&
|
SwitchSelectableVesselType(pageSelectableVessel.Target0,
|
||||||
!toggle.isOn)
|
null,
|
||||||
{
|
toggle =>
|
||||||
toggle.SetIsOnWithoutNotify(true);
|
{
|
||||||
|
if (!toggle.isOn)
|
||||||
}
|
toggle.SetIsOnWithoutNotify(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected internal override void OnPageInvisible(bool quickVisit)
|
protected internal override void OnPageInvisible(bool quickVisit)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -202,66 +218,78 @@ namespace XericUI.FlipPage
|
|||||||
pageButtonPool.Init();
|
pageButtonPool.Init();
|
||||||
|
|
||||||
// 根据组件类型创建相关内容
|
// 根据组件类型创建相关内容
|
||||||
var prefabSelectable = pageButtonPool.Prefab.GetComponent<Selectable>();
|
// var prefabSelectable = pageButtonPool.Prefab.GetComponent<Selectable>();
|
||||||
switch (prefabSelectable)
|
|
||||||
{
|
|
||||||
// 单选项就创建但选项组
|
|
||||||
case Toggle toggle:
|
|
||||||
ToggleGroup = transform.GetComponentAnyway<ToggleGroup>();
|
|
||||||
break;
|
|
||||||
case Button button:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 翻页功能
|
||||||
|
|
||||||
protected override void OnFlipPage()
|
protected override void OnFlipPage()
|
||||||
{
|
{
|
||||||
base.OnFlipPage();
|
base.OnFlipPage();
|
||||||
|
|
||||||
|
|
||||||
// 刷新所有成员的层级顺序
|
// 刷新所有成员的层级顺序
|
||||||
for (int i = 0; i < pageSelectButton.Count; i++)
|
for (int i = 0; i < pageSelectButton.Count; i++)
|
||||||
{
|
{
|
||||||
pageSelectButton[i].Target0.transform.SetSiblingIndex(i);
|
pageSelectButton[i].Target0.transform.SetSiblingIndex(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Currentpage is PageComponentInfo componentPage &&
|
||||||
|
componentPage.pageSelectableVessel.IsValidVessel())
|
||||||
|
{
|
||||||
|
SwitchSelectableVesselType(componentPage.pageSelectableVessel.Target0,
|
||||||
|
null,
|
||||||
|
toggle =>
|
||||||
|
{
|
||||||
|
if (!toggle.isOn)
|
||||||
|
toggle.isOn = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void FlipPage(int pageIndex, bool forceRefresh = false)
|
public override void FlipPage(int pageIndex, bool forceRefresh = false)
|
||||||
{
|
{
|
||||||
base.FlipPage(pageIndex, forceRefresh);
|
base.FlipPage(pageIndex, forceRefresh);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AddPageFirst(PageInfo pageInfo)
|
|
||||||
{
|
|
||||||
if (pageInfo is not PageComponentInfo componentPageInfo)
|
|
||||||
{
|
|
||||||
Debug.LogError($"页面容器{currentPage}不支持当前管理器,其必须由{nameof(FlipPageComponentManager)}.{nameof(PageComponentInfo)}继承/声名,否则无法支持后续功能", this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddPageIndexButton(componentPageInfo);
|
|
||||||
base.AddPageFirst(pageInfo);
|
|
||||||
|
|
||||||
RefreshLabelTextTotalPageCount();
|
|
||||||
RefreshPageIndeButtonState();
|
RefreshPageIndeButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddPageLast(PageInfo pageInfo)
|
public override PageInfo AddPageFirst(PageInfo pageInfo)
|
||||||
{
|
{
|
||||||
if (pageInfo is not PageComponentInfo componentPageInfo)
|
if (pageInfo is not PageComponentInfo componentPageInfo)
|
||||||
{
|
{
|
||||||
Debug.LogError($"页面容器{currentPage}不支持当前管理器,其必须由{nameof(FlipPageComponentManager)}.{nameof(PageComponentInfo)}继承/声名,否则无法支持后续功能", this);
|
Debug.LogError($"页面容器{Currentpage}不支持当前管理器,其必须由{nameof(FlipPageComponentManager)}.{nameof(PageComponentInfo)}继承/声名,否则无法支持后续功能", this);
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
// 页面基础初始化
|
||||||
|
var result = base.AddPageFirst(pageInfo);
|
||||||
|
// 添加选择按钮
|
||||||
AddPageIndexButton(componentPageInfo);
|
AddPageIndexButton(componentPageInfo);
|
||||||
base.AddPageLast(pageInfo);
|
// 刷新选择按钮显示状态
|
||||||
|
|
||||||
RefreshLabelTextTotalPageCount();
|
|
||||||
RefreshPageIndeButtonState();
|
RefreshPageIndeButtonState();
|
||||||
|
// 刷新总页数
|
||||||
|
RefreshLabelTextTotalPageCount();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override PageInfo AddPageLast(PageInfo pageInfo)
|
||||||
|
{
|
||||||
|
if (pageInfo is not PageComponentInfo componentPageInfo)
|
||||||
|
{
|
||||||
|
Debug.LogError($"页面容器{Currentpage}不支持当前管理器,其必须由{nameof(FlipPageComponentManager)}.{nameof(PageComponentInfo)}继承/声名,否则无法支持后续功能", this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 页面基础初始化
|
||||||
|
var result = base.AddPageLast(pageInfo);
|
||||||
|
// 添加选择按钮
|
||||||
|
AddPageIndexButton(componentPageInfo);
|
||||||
|
// 刷新选择按钮显示状态
|
||||||
|
RefreshPageIndeButtonState();
|
||||||
|
// 刷新总页数
|
||||||
|
RefreshLabelTextTotalPageCount();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RemovePage(int pageIndex)
|
public override void RemovePage(int pageIndex)
|
||||||
@@ -274,14 +302,44 @@ namespace XericUI.FlipPage
|
|||||||
RefreshPageIndeButtonState();
|
RefreshPageIndeButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ClearPages()
|
||||||
|
{
|
||||||
|
foreach (var pageInfo in PageInfos)
|
||||||
|
{
|
||||||
|
var page = pageInfo as PageComponentInfo;
|
||||||
|
pageButtonPool.DirectlyRelease(page.pageSelectableVessel.Target0.gameObject);
|
||||||
|
}
|
||||||
|
pageSelectButton.Clear();
|
||||||
|
base.ClearPages();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 在页面上添加按钮
|
/// 在页面上添加按钮
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pageInfo"></param>
|
/// <param name="pageInfo"></param>
|
||||||
private void AddPageIndexButton(PageComponentInfo pageInfo)
|
protected virtual void AddPageIndexButton(PageComponentInfo pageInfo)
|
||||||
{
|
{
|
||||||
var pageIndexSelectable = GetPageIndexButton();
|
var pageIndexSelectable = GetPageIndexButton();
|
||||||
pageInfo.pageIndexSelectable = pageIndexSelectable;
|
pageInfo.pageSelectableVessel = pageIndexSelectable;
|
||||||
|
// 将按钮对象添加到列表中便于管理
|
||||||
|
pageSelectButton.Add(pageIndexSelectable);
|
||||||
|
|
||||||
|
SwitchSelectableVesselType(pageIndexSelectable.Target0,
|
||||||
|
button =>
|
||||||
|
{
|
||||||
|
button.onClick.AddListener(() => FlipPage(pageInfo.pageNumber));
|
||||||
|
},
|
||||||
|
toggle =>
|
||||||
|
{
|
||||||
|
toggle.isOn = pageInfo.pageNumber == currentPageIndex;
|
||||||
|
toggle.group = ToggleGroup;
|
||||||
|
toggle.onValueChanged.AddListener(b =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
FlipPage(pageInfo.pageNumber);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
RefreshPageSelectableVesselLabel(pageInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -289,8 +347,14 @@ namespace XericUI.FlipPage
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void RefreshPageIndeButtonState()
|
private void RefreshPageIndeButtonState()
|
||||||
{
|
{
|
||||||
var min = currentPageIndex - candidatesNumber / 2;
|
var min = currentPageIndex - (int)(candidatesNumber / 2);
|
||||||
var max = currentPageIndex + candidatesNumber / 2;
|
|
||||||
|
min = Math.Max(min, 0);
|
||||||
|
min = pageSelectButton.Count - candidatesNumber > 0
|
||||||
|
? Math.Min(min, (int)(pageSelectButton.Count - candidatesNumber))
|
||||||
|
: 0;
|
||||||
|
var max = min + (int)candidatesNumber;
|
||||||
|
|
||||||
for (int i = 0; i < pageSelectButton.Count; i++)
|
for (int i = 0; i < pageSelectButton.Count; i++)
|
||||||
{
|
{
|
||||||
pageSelectButton[i].Target0.transform.SetSiblingIndex(i);
|
pageSelectButton[i].Target0.transform.SetSiblingIndex(i);
|
||||||
@@ -299,13 +363,20 @@ namespace XericUI.FlipPage
|
|||||||
if (inMaximumCandidatesNumber)
|
if (inMaximumCandidatesNumber)
|
||||||
pageSelectButton[i].Target0.gameObject.SetActive(min <= i && i <= max);
|
pageSelectButton[i].Target0.gameObject.SetActive(min <= i && i <= max);
|
||||||
else
|
else
|
||||||
pageSelectButton[i].Target0.gameObject.SetActive(min < i && i < max);
|
pageSelectButton[i].Target0.gameObject.SetActive(min <= i && i < max);
|
||||||
|
// 看不见的内容不刷新
|
||||||
|
if (!pageSelectButton[i].Target0.gameObject.activeSelf)
|
||||||
|
continue;
|
||||||
|
|
||||||
// 更新索引
|
// 更新索引
|
||||||
if (pageSelectButton[i].Target0.gameObject.activeSelf)
|
pageSelectButton[i].Target1.text = MacroRegex.RegexReplace(pageIndexFormat, i + 1);
|
||||||
{
|
|
||||||
pageSelectButton[i].Target1.text = MacroRegex.RegexReplace(pageIndexFormat, i);
|
// SwitchSelectableVesselType(pageSelectButton[i].Target0,
|
||||||
}
|
// null,
|
||||||
|
// toggle =>
|
||||||
|
// {
|
||||||
|
// toggle.SetIsOnWithoutNotify(currentPageIndex == i);
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +386,18 @@ namespace XericUI.FlipPage
|
|||||||
private void RefreshLabelTextTotalPageCount()
|
private void RefreshLabelTextTotalPageCount()
|
||||||
{
|
{
|
||||||
if (labelTextTotalPageCount.IsValidVessel()) // 总页数更新
|
if (labelTextTotalPageCount.IsValidVessel()) // 总页数更新
|
||||||
labelTextTotalPageCount.Target.text = MacroRegex.RegexReplace(totalPageCountFormat, PageInfos.Count.ToString());
|
labelTextTotalPageCount.Target.text =
|
||||||
|
MacroRegex.RegexReplace(totalPageCountFormat, PageInfos.Count.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 刷新翻页按钮索引为当前页面索引
|
||||||
|
/// </summary>
|
||||||
|
public void RefreshPageSelectableVesselLabel(PageComponentInfo page, object customInput = null)
|
||||||
|
{
|
||||||
|
if (page.pageSelectableVessel.IsValidVessel())
|
||||||
|
page.pageSelectableVessel!.Target1.text =
|
||||||
|
MacroRegex.RegexReplace(pageIndexFormat, customInput ?? page.pageNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -346,6 +428,32 @@ namespace XericUI.FlipPage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理可选对象类型,如果要支持更多的类型优先改此方法,以便获得其他所有位置的编译器提示
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="selectable"></param>
|
||||||
|
/// <param name="asButton"></param>
|
||||||
|
/// <param name="asToggle"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected static bool SwitchSelectableVesselType(Selectable selectable, Action<Button> asButton, Action<Toggle> asToggle)
|
||||||
|
{
|
||||||
|
switch (selectable)
|
||||||
|
{
|
||||||
|
case CircleSlider circleSlider: break; // asCircleSlider?.Invoke(circleSlider); break;
|
||||||
|
case TMP_Dropdown tmpDropdown: break; // asTmpDropdown?.Invoke(tmpDropdown); break;
|
||||||
|
case TMP_InputField tmpInputField: break; // asTmpInputField?.Invoke(tmpInputField); break;
|
||||||
|
case Button button: asButton?.Invoke(button); return true;
|
||||||
|
case Dropdown dropdown: break; // asDropdown?.Invoke(dropdown); break;
|
||||||
|
case InputField inputField: break; // asInputField?.Invoke(inputField); break;
|
||||||
|
case Scrollbar scrollbar: break; // asScrollbar?.Invoke(scrollbar); break;
|
||||||
|
case Slider slider: break; // asSlider?.Invoke(slider); break;
|
||||||
|
case Toggle toggle: asToggle?.Invoke(toggle); return true;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
Debug.LogError($"目前不支持的可选类型:{selectable}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Sirenix.OdinInspector;
|
using Sirenix.OdinInspector;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Serialization;
|
using UnityEngine.Serialization;
|
||||||
@@ -49,7 +50,7 @@ namespace XericUI.FlipPage
|
|||||||
[BoxGroup("设定")]
|
[BoxGroup("设定")]
|
||||||
#endif
|
#endif
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
protected int defaultItemCountPerPage = -1;
|
private int defaultItemCountPerPage = -1;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -91,6 +92,22 @@ namespace XericUI.FlipPage
|
|||||||
|
|
||||||
#region 生命周期
|
#region 生命周期
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面创建时
|
||||||
|
/// </summary>
|
||||||
|
protected internal virtual void OnPageCreated(XericFlipPageIndexVesselBase parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面销毁时
|
||||||
|
/// </summary>
|
||||||
|
protected internal virtual void OnPageDestroy(XericFlipPageIndexVesselBase parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 页面显示时
|
/// 页面显示时
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -124,6 +141,14 @@ namespace XericUI.FlipPage
|
|||||||
#endif
|
#endif
|
||||||
public string name = DateTime.Now.Ticks.ToString();
|
public string name = DateTime.Now.Ticks.ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从零开始计数的项目下标
|
||||||
|
/// </summary>
|
||||||
|
#if ODIN_INSPECTOR
|
||||||
|
[LabelText("项目索引[0, n]")]
|
||||||
|
#endif
|
||||||
|
public int itemNumber { get; internal set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 生命周期
|
#region 生命周期
|
||||||
@@ -159,9 +184,20 @@ namespace XericUI.FlipPage
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
protected int currentPageIndex = 0;
|
protected int currentPageIndex = 0;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
/// <summary>
|
||||||
|
/// 显示调试列表
|
||||||
|
/// </summary>
|
||||||
|
#if ODIN_INSPECTOR
|
||||||
|
[ShowInInspector]
|
||||||
|
#endif
|
||||||
|
private List<PageInfo> PageInfoLists => _pageInfos.ToList();
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 所有页面
|
/// 所有页面
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
private LinkedList<PageInfo> _pageInfos = new LinkedList<PageInfo>();
|
private LinkedList<PageInfo> _pageInfos = new LinkedList<PageInfo>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -169,11 +205,11 @@ namespace XericUI.FlipPage
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private HashSet<ItemInfo> _itemInfos = new HashSet<ItemInfo>();
|
private HashSet<ItemInfo> _itemInfos = new HashSet<ItemInfo>();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前选中页面节点
|
/// 当前选中页面节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LinkedListNode<PageInfo> currentPageNode = null;
|
protected LinkedListNode<PageInfo> CurrentPageNode = null;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 所有页面
|
/// 所有页面
|
||||||
@@ -183,7 +219,21 @@ namespace XericUI.FlipPage
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前选中页面内容
|
/// 当前选中页面内容
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PageInfo currentPage => currentPageNode.Value;
|
public PageInfo Currentpage => CurrentPageNode?.Value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分布于所有页面上的所有数据项目
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<ItemInfo> AllItemInfos => _pageInfos.SelectMany(page => page.itemInfos);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面默认最大项目数量
|
||||||
|
/// </summary>
|
||||||
|
protected int DefaultItemCountPerPage
|
||||||
|
=> defaultItemCountPerPage < 0 ? int.MaxValue : defaultItemCountPerPage;
|
||||||
|
|
||||||
|
|
||||||
|
private List<ItemInfo> _backupItemInfos;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -222,7 +272,7 @@ namespace XericUI.FlipPage
|
|||||||
{
|
{
|
||||||
if (float.TryParse(pageNumber, out var index))
|
if (float.TryParse(pageNumber, out var index))
|
||||||
{
|
{
|
||||||
FlipPage((int)index, forceRefresh);
|
FlipPage((int)index - 1, forceRefresh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +289,7 @@ namespace XericUI.FlipPage
|
|||||||
(pageIndex < 0 || pageIndex >= _pageInfos.Count))
|
(pageIndex < 0 || pageIndex >= _pageInfos.Count))
|
||||||
pageIndex = Mathf.Clamp(pageIndex, 0, _pageInfos.Count - 1);
|
pageIndex = Mathf.Clamp(pageIndex, 0, _pageInfos.Count - 1);
|
||||||
else
|
else
|
||||||
pageIndex = MacroMath.PMod(pageIndex, _pageInfos.Count - 1);
|
pageIndex = MacroMath.PMod(pageIndex, _pageInfos.Count);
|
||||||
// 检查翻页数量有效
|
// 检查翻页数量有效
|
||||||
if (!forceRefresh && currentPageIndex == pageIndex)
|
if (!forceRefresh && currentPageIndex == pageIndex)
|
||||||
return;
|
return;
|
||||||
@@ -247,23 +297,23 @@ namespace XericUI.FlipPage
|
|||||||
var pageIndexOffset = pageIndex - currentPageIndex;
|
var pageIndexOffset = pageIndex - currentPageIndex;
|
||||||
var lastPageIndex = currentPageIndex;
|
var lastPageIndex = currentPageIndex;
|
||||||
// 如果节点不存在,通过索引寻找
|
// 如果节点不存在,通过索引寻找
|
||||||
if (currentPageNode == null)
|
if (CurrentPageNode == null)
|
||||||
currentPageNode = _pageInfos.GetOrderNode().LandedIndex(currentPageIndex);
|
CurrentPageNode = _pageInfos.GetOrderNode().LandedIndex(currentPageIndex);
|
||||||
// 如果索引偏移,逐个移动
|
// 如果索引偏移,逐个移动
|
||||||
else if (pageIndexOffset > 0)
|
else if (pageIndexOffset > 0)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < pageIndexOffset; i++)
|
for (var i = 0; i < pageIndexOffset; i++)
|
||||||
{
|
{
|
||||||
var next = currentPageNode!.Next;
|
var next = CurrentPageNode!.Next;
|
||||||
SwitchPage(next, _pageInfos.Last, i + 1 == pageIndexOffset);
|
SwitchPage(next, _pageInfos.Last, i + 1 < pageIndexOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pageIndexOffset < 0)
|
else if (pageIndexOffset < 0)
|
||||||
{
|
{
|
||||||
for (var i = 0; i > pageIndexOffset; i--)
|
for (var i = 0; i > pageIndexOffset; i--)
|
||||||
{
|
{
|
||||||
var previa = currentPageNode!.Previous;
|
var previa = CurrentPageNode!.Previous;
|
||||||
SwitchPage(previa, _pageInfos.First, i - 1 == pageIndexOffset);
|
SwitchPage(previa, _pageInfos.First, i - 1 > pageIndexOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 没有翻动有效页,退出
|
// 没有翻动有效页,退出
|
||||||
@@ -278,16 +328,16 @@ namespace XericUI.FlipPage
|
|||||||
{
|
{
|
||||||
if (newPageNode != null)
|
if (newPageNode != null)
|
||||||
{
|
{
|
||||||
currentPage.OnPageInvisible(quickPage);
|
Currentpage.OnPageInvisible(quickPage);
|
||||||
currentPageNode = newPageNode;
|
CurrentPageNode = newPageNode;
|
||||||
currentPage.OnPageVisible(quickPage);
|
Currentpage.OnPageVisible(quickPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canPassIndexBoundary)
|
if (canPassIndexBoundary)
|
||||||
{
|
{
|
||||||
currentPage.OnPageInvisible(quickPage);
|
Currentpage.OnPageInvisible(quickPage);
|
||||||
currentPageNode = defualtPageNode;
|
CurrentPageNode = defualtPageNode;
|
||||||
currentPage.OnPageVisible(quickPage);
|
Currentpage.OnPageVisible(quickPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,44 +381,49 @@ namespace XericUI.FlipPage
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加页面在开头
|
/// 添加页面在开头
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void AddPageFirst(PageInfo pageInfo)
|
public virtual PageInfo AddPageFirst(PageInfo pageInfo)
|
||||||
{
|
{
|
||||||
if (pageInfo == null)
|
if (pageInfo == null)
|
||||||
{
|
{
|
||||||
Debug.LogError($"不能添加一个空的页面内容到管理器中!", this);
|
Debug.LogError($"不能添加一个空的页面内容到管理器中!", this);
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加页面
|
|
||||||
_pageInfos.AddFirst(pageInfo);
|
|
||||||
// 添加页面下标
|
// 添加页面下标
|
||||||
pageInfo.pageNumber = 0;
|
pageInfo.pageNumber = 0;
|
||||||
|
// 添加页面
|
||||||
|
_pageInfos.AddFirst(pageInfo);
|
||||||
// 更新后面页面的索引
|
// 更新后面页面的索引
|
||||||
RefreshAllPageNumber();
|
RefreshAllPageNumber();
|
||||||
|
// 执行页面生命周期
|
||||||
|
pageInfo.OnPageCreated(this);
|
||||||
// 刷新页面
|
// 刷新页面
|
||||||
FlipPage(currentPageIndex, true);
|
FlipPage(currentPageIndex, true);
|
||||||
|
return pageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加页面在结尾
|
/// 添加页面在结尾
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void AddPageLast(PageInfo pageInfo)
|
public virtual PageInfo AddPageLast(PageInfo pageInfo)
|
||||||
{
|
{
|
||||||
if (pageInfo == null)
|
if (pageInfo == null)
|
||||||
{
|
{
|
||||||
Debug.LogError($"不能添加一个空的页面内容到管理器中!", this);
|
Debug.LogError($"不能添加一个空的页面内容到管理器中!", this);
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
// 添加页面下标
|
// 添加页面下标
|
||||||
pageInfo.pageNumber = _pageInfos.Count;
|
pageInfo.pageNumber = _pageInfos.Count;
|
||||||
// 添加页面
|
// 添加页面
|
||||||
_pageInfos.AddLast(pageInfo);
|
_pageInfos.AddLast(pageInfo);
|
||||||
|
// 执行页面生命周期
|
||||||
|
pageInfo.OnPageDestroy(this);
|
||||||
// 刷新页面
|
// 刷新页面
|
||||||
FlipPage(currentPageIndex, true);
|
FlipPage(currentPageIndex, true);
|
||||||
|
return pageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 移除页面
|
/// 移除页面(页面上的数据内容也会一同移除)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void RemovePage(int pageIndex)
|
public virtual void RemovePage(int pageIndex)
|
||||||
{
|
{
|
||||||
@@ -388,23 +443,50 @@ namespace XericUI.FlipPage
|
|||||||
tempPage.Value.pageNumber = tempPageNumber++;
|
tempPage.Value.pageNumber = tempPageNumber++;
|
||||||
}
|
}
|
||||||
// 如果移除的是当前页面,执行关闭操作
|
// 如果移除的是当前页面,执行关闭操作
|
||||||
if (currentPageNode == page)
|
if (CurrentPageNode == page)
|
||||||
{
|
{
|
||||||
page.Value.OnPageInvisible(true);
|
page.Value.OnPageInvisible(true);
|
||||||
currentPageNode = null;
|
CurrentPageNode = null;
|
||||||
}
|
}
|
||||||
|
// 执行页面生命周期
|
||||||
|
page.Value.OnPageDestroy(this);
|
||||||
|
// 页面索引移除
|
||||||
_pageInfos.Remove(page);
|
_pageInfos.Remove(page);
|
||||||
// 刷新页面
|
// 刷新页面
|
||||||
FlipPage(currentPageIndex, true);
|
FlipPage(currentPageIndex, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 清除所有页面
|
/// 仅移除页面,不会移除数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void CleanPage()
|
/// <param name="pageIndex"></param>
|
||||||
|
public void RemovePageWithoutItems(int pageIndex)
|
||||||
|
{
|
||||||
|
BackupItemsFormPages();
|
||||||
|
RemovePage(pageIndex);
|
||||||
|
RestoreItemsToPages();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取索引下的页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pageIndex"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T IndexOfPageInfo<T>(int pageIndex)
|
||||||
|
where T : PageInfo
|
||||||
|
=> _pageInfos.LandedIndex(pageIndex) as T;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除所有页面 (所有页面数据也会一同移除)
|
||||||
|
/// </summary>
|
||||||
|
#if ODIN_INSPECTOR
|
||||||
|
[HorizontalGroup("数据"), Button("清除所有页面")]
|
||||||
|
#endif
|
||||||
|
public virtual void ClearPages()
|
||||||
{
|
{
|
||||||
_pageInfos.Clear();
|
_pageInfos.Clear();
|
||||||
currentPageNode = null;
|
CurrentPageNode = null;
|
||||||
currentPageIndex = 0;
|
currentPageIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,5 +518,128 @@ namespace XericUI.FlipPage
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 数据项目
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加数据项目
|
||||||
|
/// </summary>
|
||||||
|
public void AddItem(ItemInfo item, Func<PageInfo> addPage)
|
||||||
|
{
|
||||||
|
// 向前寻找空缺(这在页面都被准确填充的情况下最忧)
|
||||||
|
var firstVacancy = _pageInfos
|
||||||
|
.GetReversedOrderNode()
|
||||||
|
.LastOrDefault(a
|
||||||
|
=> a.Value.itemInfos.Count < DefaultItemCountPerPage);
|
||||||
|
if (firstVacancy != null)
|
||||||
|
{
|
||||||
|
firstVacancy.Value.itemInfos.Add(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (addPage == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("当前页面已满,数据项目顺位添加到新页面中,但未指定页面创建函数,添加过程已退出", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 新建一个页面存放数据
|
||||||
|
addPage.Invoke().itemInfos.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除所有包含给定项目的位置(这会在页面上留下空缺)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
public void RemoveItem(ItemInfo item)
|
||||||
|
{
|
||||||
|
foreach (var a in AllItemInfos
|
||||||
|
.Adjoint()
|
||||||
|
.Where(a => a.obj == item)
|
||||||
|
.Reverse())
|
||||||
|
{
|
||||||
|
ItemIndex2PageIndex(a.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveItem(int indexItem)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保留页面的状态下清空所有数据
|
||||||
|
/// </summary>
|
||||||
|
#if ODIN_INSPECTOR
|
||||||
|
[HorizontalGroup("数据"), Button("清除所有数据")]
|
||||||
|
#endif
|
||||||
|
public void ClearItemsWithoutPages()
|
||||||
|
{
|
||||||
|
foreach (var page in _pageInfos)
|
||||||
|
{
|
||||||
|
page.itemInfos.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用索引定位到数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="itemIndex"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public T IndexOfItemInfo<T>(int itemIndex)
|
||||||
|
where T : ItemInfo
|
||||||
|
=> AllItemInfos.LandedIndex(itemIndex) as T;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将项目索引转为页面索引
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="itemIndex"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual int ItemIndex2PageIndex(int itemIndex)
|
||||||
|
{
|
||||||
|
return itemIndex / DefaultItemCountPerPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备份所有数据项目
|
||||||
|
/// </summary>
|
||||||
|
public void BackupItemsFormPages()
|
||||||
|
{
|
||||||
|
_backupItemInfos = AllItemInfos.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存所有数据项目(强制重排操作)
|
||||||
|
/// </summary>
|
||||||
|
public void RestoreItemsToPages()
|
||||||
|
{
|
||||||
|
if (ItemIndex2PageIndex(_backupItemInfos.Count - 1) > _pageInfos.Count)
|
||||||
|
{
|
||||||
|
Debug.LogError($"重排数据时,原有数据数量({_backupItemInfos.Count})超出现有面板数量({_pageInfos.Count}),已拒绝重排", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 执行重拍
|
||||||
|
var page = _pageInfos.First;
|
||||||
|
page.Value.itemInfos.Clear();
|
||||||
|
var pageIndex = 0;
|
||||||
|
for (int i = 0; i < _backupItemInfos.Count; i++)
|
||||||
|
{
|
||||||
|
var newPageIndex = ItemIndex2PageIndex(i);
|
||||||
|
if (pageIndex != newPageIndex)
|
||||||
|
{
|
||||||
|
pageIndex = newPageIndex;
|
||||||
|
page = page.Next;
|
||||||
|
if (page == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"重排数据时,页面链接错误,重排被迫中断", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
page.Value.itemInfos.Clear();
|
||||||
|
}
|
||||||
|
page.Value.itemInfos.Add(_backupItemInfos[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user