原理:
复用几个子物体,通过子物体的循环移动实现,如下图
在第一个子物体滑动到超出一定数值时,使其放到最下方
--------------------------------------------------------------》
然后不停的循环往复,向下滑动也是这样的原理
下边上代码:
首先得到Scorll View的高度,使用UIpanel获取,
UIPanel uiPanel = this.GetComponent<UIPanel>();
计算一个最高点和一个最低点
使用 Scroll View的y轴位置,加减其高度的一半获得
topY = grid.transform.TransformPoint(new Vector3(0, uiPanel.height / 2 + this.transform.position.y, 0));
bottomY = grid.transform.TransformPoint(new Vector3(0, this.transform.position.y - uiPanel.height / 2, 0));
为什么要转换为世界坐标呢?
首先要看一下Grid和Item是如何滑动的,如下:
可以发现滑动的时候,Grid和子物体面板上的坐标压根不变,显示的都是本地坐标,所以要用一个变量来判断,就必须转换到世界空间下的坐标,有了这个就可以进行判断了,代码如下:(目前代码不是最优,中间增加了没有必要的判断,后边会优化掉)。
// 处理向上滚动
for (int i = 0;i < visibleItems.Count; i++)
{
if (grid.transform.TransformPoint(visibleItems[i].transform.localPosition).y > topY.y)
{
}
}
// 处理向下滚动
for (int i = 0; i < visibleItems.Count; i++)
{
if (grid.transform.TransformPoint(visibleItems[i].transform.localPosition).y < bottomY.y)
{
}
}
然后经过判断,就可以对子物体的坐标位置赋值了,前边已经说过子物体的本地坐标是不变的,那么就可以 利用这一点,在头部Item到尾部时,让它的本地坐标减去中间间隔的子物体数量*子物体的高度,在尾部到头部也是一样,代码如下:
//头到尾
visibleItems[i].transform.localPosition = new Vector3(0, visibleItems[i].transform.localPosition.y - visibleItemCount * 100, 0);
//尾到头
visibleItems[i].transform.localPosition = new Vector3(0, visibleItems[i].transform.localPosition.y + visibleItemCount * 100, 0);
如何判断向上还是向下滑动?
记录grid的世界坐标,如果这一帧的值比上一帧的值小,则是向下,否则是向上,并在Update函数下执行,使用一个bool值,使其只在拖动列表的时候执行,代码如下:
private void Update()
{
if (isDrag)
{
currentPosition = grid.transform.position.y;
// 处理向上滚动
if (currentPosition > lastPosition)
{
}
// 处理向下滚动
else if (currentPosition < lastPosition)
{
}
lastPosition = currentPosition;
}
}
这个bool值如何赋值?
使用Scroll View的两个函数.onDragStarted,onDragFinished,在代码中给这两个函数分别绑定改变这个bool的值的函数即可。
最后结果: