Unity 中实现可翻页的 PageView
之前已经实现过:
Unity 中实现可复用的 ListView-CSDN博客文章浏览阅读5.6k次,点赞2次,收藏27次。源码已放入我的 github,地址:Unity-ListView前言实现一个列表组件,表现方面最核心的部分就是重写布局(Layout)。对于简单的列表,尤其是“Cell数量固定且较少、没有超页滚动展示”一类的需求,使用UGUI自带的布局组件进行布局即可。分别为:水平布局组件(Horizontal Layout Group)、竖直布局组件(Vertical Layout Gro..._unity listviewhttps://blog.csdn.net/NRatel/article/details/100561203Unity 中实现可复用的 GridView-CSDN博客文章浏览阅读4k次。本文介绍了如何基于Unity的UGUI系统设计一个灵活的GridView组件。作者分析了GridLayoutGroup的参数,讨论了StartCorner和StartAxis的排布方式、Constraint的灵活性以及Padding与对齐方式的巧妙结合。在实现过程中,修改了ScrollRect的关联ScrollBar和布局接口,设计了适应不同滑动方向的布局,并实现了元素复用逻辑,包括四种滑动方向的计算。此外,还探讨了Content锚点、行列约束和对齐方式的调整,以提高组件的易用性。
https://blog.csdn.net/NRatel/article/details/124063559Unity 中实现首尾无限循环的 ListView-CSDN博客文章浏览阅读1.3k次,点赞21次,收藏23次。以 ListView 为基础。参照 GrideView 修改 ListView:使其 继承 UIScrollRect(原因是必须修改部分源码)并支持参数:MovementAxis、StartSide、ChildAligment实现几个要点......
https://blog.csdn.net/NRatel/article/details/148335474可翻页的 PageView,还是以 ListView 为基础(支持已实现的ListView的全部功能)。
支持要点:
(以下仅以 MovementAxis=Horizontal,StartSide=Left 的情形阐述)
1、自动吸附对齐(Snap)
滑动放手后(若开启惯性滑动,则为停稳后),要自动将Cell吸附对齐到Viewport中心,没有自动吸附对齐,就不能产生Page的概念。
将吸附到哪一页,由“放手/停稳时位置” 决定, 接近哪一页就吸附到哪一页。
可配置:
①、是否启用(目前强制启用,否则将退化为 UIListView)
②、吸附/对齐速度(每帧移动的像素数)
③、开启惯性时,等待基本停稳才开始Snap,停稳阈值
2、翻页类型(CellOccupyPage)
是否勾选,决定两种展现形式:
①、保持List形式;
②、Cell 在滑动方向上独占一页(调整Spacing)
3、是否自动轮播(Carousel)
可配置:
①、是否启用
②、轮播翻页速度每帧移动的像素数)
③、翻页间隔/页停留时间
④、是否反向轮播
实现要点:
1、paddingLeft、paddingRight。
需强设:paddingLeft = paddingRight = (Viewport宽度 - Cell宽度)/2。
因为要保证第一个和最后一个Cell能够处于Viewport的中心。
这个计算方式对 “Cell宽度 <= Viewport宽度” 和 “Cell宽度 > Viewport宽度”的情况都是适用的。
//调整边距(注意只调整滑动方向)
protected override void FixPadding()
{if (m_Loop){base.FixPadding();}else{if (m_MovementAxis == MovementAxis.Horizontal){int fixedPaddingX = Mathf.FloorToInt((m_Viewport.rect.width - m_CellRect.width) / 2);padding.left = padding.right = fixedPaddingX;}else{int fixedPaddingY = Mathf.FloorToInt((m_Viewport.rect.height - m_CellRect.height) / 2);padding.top = padding.bottom = fixedPaddingY;}}
}
2、spacingX
若勾选 CellOccupyPage,需强设:spacingX = Viewport宽度 - Cell宽度;
//调整间距(注意只调整滑动方向)
protected override void FixSpacing()
{if (!m_CellOccupyPage) { return; }if (m_MovementAxis == MovementAxis.Horizontal){float fixedSpacingX = m_Viewport.rect.width - m_CellRect.width;spacing = new Vector2(fixedSpacingX, spacing.y);}else{float fixedSpacingY = m_Viewport.rect.height - m_CellRect.height;spacing = new Vector2(spacing.x, fixedSpacingY);}
}
3、Snap 实现:
①、找离Viewport中心最近的那个Cell
遍历正在显示的Cell(一般数量较少,无需担心性能),分别计算每个Cell离Viewport中心的距离,找出最近的那个
②、与回弹的冲突
若开启边界回弹,则需等待回弹结束,再开始 Snap
有阈值,但不支持外部自定义(应固定实现好)
③、与惯性速度的冲突
若开启惯性速度,则需等待停稳,再开始 Snap
有阈值,支持外部自定义(影响节奏)
4、Carousel 实现:
①、在协程中等待计时
②、若当前处于非最后一页,则翻到下一页;若当前处于最后一页,则迅速反向翻回到第一页
③、支持反向轮播
5、StartShow、BeginDrag、EndDrag、Snap、Carousel 的闭环衔接(核心流程)
StartShow 时: TryStartSnap
BeginDrag 时: TryStopSnap、TryStopCarousel
EndDrag 时: TryStartSnap
Snap 结束时: TryStartCarousel
Carousel 结束时: TryStartSnap
6、loop (首尾无限循环)对 PageView 的影响
①、首尾无限循环没有“边界”,自然就没有“边距”可言。但实际上,它还影响首页初始位置。因此此时无需修改 padding,而是保持用户指定值
②、开启循环时, 总是向后翻到下一页,无需在最后一页时,迅速翻回首页
③、因为 loop 会重置 Content 的位置,所以 Snap 和 Carousel 时的移动插值不能是 “从当前位置到目标点”了,而是要变成“累计移动量”
----------------------------------------- NRatel割 -----------------------------------------
实现效果:
启用 CellOccupyPage
源码:GitHub - NRatel/Unity-ListView基于UnityUGUI,实现标准的可复用Cell的列表视图。包括一些特殊需求,持续整合中。。. Contribute to NRatel/Unity-ListView development by creating an account on GitHub.https://github.com/NRatel/Unity-ListView