UGUI实现ScrollView无限滚动效果

  

抽空做了一个UGUI的无限滚动的效果,只做了一半(向下无限滚动)。网上也看了很多教程,感觉还是按照自己的思路来写可能比较好。搭建如下:

  

 UGUI实现ScrollView无限滚动效果

  

内容节点不添加任何组件。布局组件默认是会重新排版子节点的,所以如果子节点的位置变化,会重新排版,不能达到效果.Size钳工组件也不加,自己写代码调整大尺寸小(不调整大小,无法滑动)。

  

最主要的实现过程就是用队列来搬运细胞。在向下滚动的过程中(鼠标上滑),顶部滑出视图端口的细胞被搬运到底部续上。这点类似于队列的先见先出原则,再把出列出来的元素添加到末尾,就很类似于滚动视图的无限滚动的原理了。在鼠标上滑的过程中,内容的诗句值是一直增加的,所以触发滚动的条件就可以设定为位移之差大于细胞的高度值即可。

  

,数据的刷新,数据到头之后,不能再次进行滚动轮换了,这里用一组值来记录初始化的一组细胞显示的是数据的哪一段,例如HeadNum和TaiNum。比如用20个细胞显示100条数据。初始化后,HeadNum就是0,TailNum就是19。上滑一行数据后,HeadNum=4, TailNum=23(这里假设是20个细胞排成4列)。

  

下面是完整代码:

        公共类UIScrollViewTest: MonoBehaviour {      公共RectTransform内容;   公共GameObject细胞;//单元格的初始化个数   公共int cellAmount=0;//鼠标上滑时,存储单元的队列。正序存储   公共队列F_cellQuee=new队列();//鼠标下滑时,存储单元的队列中。到序存储   公共队列B_cellQuee=new队列();//单元格的大小   公共Vector2 cellSize=new Vector2 (100100);//细胞的间隔   公共Vector2 cellOffset=new Vector2 (0,0);//列数   公共int columnCount=0;   私人int rowCount;//上一次内容的位置   公共lastPos浮动;//滚动的次数   公共int loopCount=0;//细胞显示的数据段的开头和结尾序号   公共int HeadNum=0;   公共int TailNum;      公共雪碧[]sp;   公共List数据;         无效的Start ()   {   for (int i=0;我& lt;sp.Length;我+ +)   {   [我]data.Add (sp);   }      InitialScrollView(数据);   TailNum=cellAmount-1;   lastPos=content.localPosition.y;//调试。LogError(“行数是:::“+ rowCount);//调试。LogError(“+ + + + + + + + + + + + + + + + + +(5比,比;3));   }         无效的更新()   {//触发滚动。   如果(content.localPosition。y - lastPos比;cellSize。y,和数据。Count - cellAmount loopCount * columnCount祝辞0)   {//调试。LogError(“11111111111”+(数据。数- cellAmount loopCount * columnCount));   LoopScrolView(数据);   lastPos=content.localPosition.y;   }   }//初始化细胞   空白InitialScrollView (List数据)   {   for (int i=0;我& lt;cellAmount;我+ +)   {   GameObject obj=实例化(cell.gameObject);   obj.transform.SetParent(内容);   obj.name=" cell0 " + i.ToString ();   obj.transform.GetChild (0) .GetComponent ()。文本=" cell0 " + i.ToString ();//显示默认的数据   obj.GetComponent ()。雪碧=数据(我);   }//初始化队列   for (int i=content.childCount-1;我在=0;我——)   {   B_cellQuee.Enqueue (content.GetChild(我).gameObject);   }   for (int i=0;我& lt;content.childCount;我+ +)   {   F_cellQuee.Enqueue (content.GetChild(我).gameObject);   }//计算行数   如果(cellAmount % columnCount祝辞0)   {   rowCount=cellAmount/columnCount + 1;   其他}{   rowCount=cellAmount/columnCount;   }//排列单元的位置   int指数=0;   for (int r=1;r & lt;=rowCount;r + +)   {   for (int c=1;c & lt;=columnCount;c++)   {   如果(指数& lt;cellAmount)   {   Vector2 pos=new Vector2 (cellSize。x/2 + (cellSize。颈- 1 x + cellOffset.x) * (), -cellSize。y/2 - (cellOffset。y + cellSize.y) * (r1));   content.GetChild(指数).GetComponent () .SetInsetAndSizeFromParentEdge (RectTransform.Edge。,0,100);   content.GetChild(指数).GetComponent () .SetInsetAndSizeFromParentEdge (RectTransform.Edge。离开,0,100);   content.GetChild(索引).GetComponent ()。anchoredPosition=pos;   指数+ +;   }   }   }      Vector2 v=content.sizeDelta;//初始化内容的大小   内容。sizeDelta=new Vector2 (v。x, rowCount * cellSize。y + cellOffset.y * (rowCount-1));   }///保持内容的大小,这里是保持大小为在细胞的行数基础上,向下多出bottomCount行的距离   空白SetContentSize (int upperCount int bottomCount)   {   如果内容。sizeDelta !=新Vector2 (content.sizeDelta。x, content.sizeDelta。y + bottomCount * (cellSize。y + cellOffset.y)))   {   内容。sizeDelta=new Vector2 (content.sizeDelta。x, content.sizeDelta。y + bottomCount * (cellSize。y + cellOffset.y));   }   }//计算顶部的细胞轮换到底部时的位置,以当前最后一行的最后一个单元的位置为基准计算。   空白SetBottomCellPosition (int指数,RectTransform矩形,Vector2 pos)   {   Vector2 v=Vector2.zero;   如果(cellAmount % columnCount==0)//整除。每一行都满的情况。   {   x=pos.x - cellSize浮动。x * (columnCount -索引1)- cellOffset。x * (columnCount-index-1);   y=pos.y - cellSize浮动。y - cellOffset.y;   v=new Vector2 (x, y);   }//出现不满行的情况,例如数据有103个,可以用23个细胞来轮换。这样就会出现不满行的情况。//这种情况下是顶部的一行单元格顺次接到底部不满的行,例如23号细胞后面接1号和2号,3号和4号细胞填充到第“7”行   else if (cellAmount % columnCount +指数+ 1 & lt;=columnCount)   {   x=pos.x + cellSize浮动。x *(指数+ 1)+ cellOffset。x *(指数+ 1);   浮动y=pos.y;   v=new Vector2 (x, y);   }   其他的   {   x=pos.x - cellSize浮动。x * (columnCount -索引1)- cellOffset。x * (columnCount -索引1);   y=pos.y - cellSize浮动。y - cellOffset.y;   v=new Vector2 (x, y);   }//调试。LogError (“+ + + + + + + + + + + + + +”+ pos + " " + v);   rect.anchoredPosition=v;   rect.SetAsLastSibling ();   }//计算底部的细胞轮换到顶部是的位置,基准位置是当前行的第一个细胞。   空白SetUpperCellPosition (int指数,RectTransform矩形,Vector2 pos)   {   Vector2 v=Vector2.zero;   如果(cellAmount % columnCount==0)//整除   {   x=pos.x + cellSize浮动。x *指数+ cellOffset。x *指数;   y=pos.y + cellSize浮动。y + cellOffset.y;   v=new Vector2 (x, y);   }//else if (cellAmount % columnCount +指数+ 1 & lt;=columnCount)//{//x=pos.x + cellSize浮动。x *(指数+ 1)+ cellOffset。null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

UGUI实现ScrollView无限滚动效果