国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

UGUI實現ScrollView無限滾動效果

2020-01-24 00:08:56
字體:
來源:轉載
供稿:網友

抽空做了一個UGUI的無限滾動的效果。只做了一半(向下無限滾動)。網上也看了很多教程,感覺還是按照自己的思路來寫可能比較好。搭建如下:

content節點不添加任何組件。布局組件默認是會重新排版子節點的,所以如果子節點的位置變化,會重新排版,不能達到效果。Size Fitter組件也不加,自己寫代碼調整Size大小(不調整大小,無法滑動)。

最主要的實現過程就是用Queue來搬運Cell。在向下滾動的過程中(鼠標上滑),頂部滑出View Port的Cell被搬運到底部續上。這點類似于Queue的先見先出原則,再把Dequeue出來的元素添加到末尾,就很類似于ScrollView的無限滾動的原理了。在鼠標上滑的過程中,content的PosY值是一直增加的,所以觸發滾動的條件就可以設定為位移之差大于Cell的高度值即可。

 數據的刷新,數據到頭之后,不能再次進行滾動輪換了,這里用一組值來記錄初始化的一組Cell顯示的是數據的哪一段。例如HeadNum和TaiNum。比如用20個Cell顯示100條數據。初始化后,HeadNum就是0,TailNum就是19。上滑一行數據后,HeadNum=4,TailNum=23(這里假設是20個Cell排成4列)。

下面是完整代碼:

public class UIScrollViewTest : MonoBehaviour {  public RectTransform content; public GameObject cell; // cell的初始化個數 public int cellAmount = 0; // 鼠標上滑時,存儲Cell的Queue。正序存儲 public Queue F_cellQuee = new Queue(); // 鼠標下滑時,存儲Cell的Queue。到序存儲 public Queue B_cellQuee = new Queue(); // cell的Size public Vector2 cellSize = new Vector2(100,100); // cell的間隔 public Vector2 cellOffset = new Vector2(0,0); // 列數 public int columnCount = 0; private int rowCount; // 上一次content的位置 public float lastPos; // 滾動的次數 public int loopCount = 0; // cell顯示的數據段的開頭和結尾序號 public int HeadNum = 0; public int TailNum;  public Sprite[] sp; public List<Sprite> data;   void Start() {  for (int i = 0; i < sp.Length; i++)  {   data.Add(sp[i]);  }   InitialScrollView(data);  TailNum = cellAmount-1;  lastPos = content.localPosition.y;  //Debug.LogError("行數是:::" + rowCount);   //Debug.LogError("+++++++++++++++++ " + (5>>3)); }   void Update() {  // 觸發滾動。  if (content.localPosition.y - lastPos > cellSize.y && data.Count - cellAmount - loopCount*columnCount >0)  {   //Debug.LogError("11111111111 " + (data.Count - cellAmount - loopCount * columnCount));   LoopScrolView(data);   lastPos = content.localPosition.y;  } }     // 初始化cell void InitialScrollView(List<Sprite> data) {  for (int i = 0; i < cellAmount; i++)  {   GameObject obj = Instantiate(cell.gameObject);   obj.transform.SetParent(content);   obj.name = "cell0" + i.ToString();   obj.transform.GetChild(0).GetComponent<Text>().text = "cell0"+i.ToString();   // 顯示默認的數據   obj.GetComponent<Image>().sprite = data[i];  }  // 初始化Queue  for (int i = content.childCount-1; i >= 0; i--)  {   B_cellQuee.Enqueue(content.GetChild(i).gameObject);  }  for (int i = 0; i < content.childCount; i++)  {   F_cellQuee.Enqueue(content.GetChild(i).gameObject);  }   // 計算行數  if (cellAmount % columnCount >0)  {   rowCount = cellAmount / columnCount + 1;  } else {   rowCount = cellAmount / columnCount;  }   // 排列cell的位置  int index = 0;  for (int r = 1; r <= rowCount; r++)  {   for (int c = 1; c <= columnCount; c++)   {    if (index < cellAmount)    {     Vector2 pos = new Vector2(cellSize.x / 2 + (cellSize.x + cellOffset.x) * (c-1), -cellSize.y / 2 - (cellOffset.y + cellSize.y) * (r-1));     content.GetChild(index).GetComponent<RectTransform>().SetInsetAndSizeFromParentEdge(RectTransform.Edge.Top, 0, 100);     content.GetChild(index).GetComponent<RectTransform>().SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, 0, 100);     content.GetChild(index).GetComponent<RectTransform>().anchoredPosition = pos;     index++;    }   }  }   Vector2 v = content.sizeDelta;  // 初始化content的size  content.sizeDelta = new Vector2(v.x, rowCount * cellSize.y + cellOffset.y*(rowCount-1)); }   /// 保持content的大小,這里是保持大小為在cell的行數基礎上,向下多出bottomCount行的距離 void SetContentSize(int upperCount, int bottomCount) {  if (content.sizeDelta != new Vector2(content.sizeDelta.x, content.sizeDelta.y + bottomCount * (cellSize.y + cellOffset.y)))  {   content.sizeDelta = new Vector2(content.sizeDelta.x, content.sizeDelta.y + bottomCount*(cellSize.y + cellOffset.y));  } }  // 計算頂部的Cell輪換到底部時的位置。以當前最后一行的最后一個Cell的位置為基準計算。 void SetBottomCellPosition(int index, RectTransform rect, Vector2 pos) {  Vector2 v = Vector2.zero;  if (cellAmount % columnCount == 0) // 整除。每一行都滿的情況。  {   float x = pos.x - cellSize.x * (columnCount - index-1) - cellOffset.x * (columnCount-index-1);   float y = pos.y - cellSize.y - cellOffset.y;   v = new Vector2(x,y);  }  // 出現不滿行的情況。例如數據有103個,可以用23個cell來輪換。這樣就會出現不滿行的情況。  // 這種情況下是頂部的一行cell順次接到底部不滿的行。例如23號cell后面接1號和2號cell,3號和4號cell填充到第“7”行  else if (cellAmount % columnCount + index+1<=columnCount)   {   float x = pos.x + cellSize.x * (index+1) + cellOffset.x * (index+1);   float y = pos.y;   v = new Vector2(x, y);  }  else  {   float x = pos.x - cellSize.x * (columnCount - index-1) - cellOffset.x * (columnCount - index-1);   float y = pos.y - cellSize.y - cellOffset.y;   v = new Vector2(x, y);  }  //Debug.LogError("++++++++++++++ " + pos+ "     "+ v);  rect.anchoredPosition = v;  rect.SetAsLastSibling(); }  // 計算底部的cell輪換到頂部是的位置,基準位置是當前行的第一個cell。 void SetUpperCellPosition(int index, RectTransform rect, Vector2 pos) {  Vector2 v = Vector2.zero;  if (cellAmount % columnCount == 0) // 整除  {   float x = pos.x + cellSize.x * index + cellOffset.x * index;   float y = pos.y + cellSize.y + cellOffset.y;   v = new Vector2(x, y);  }  //else if (cellAmount % columnCount + index + 1 <= columnCount)  //{  // float x = pos.x + cellSize.x * (index + 1) + cellOffset.x * (index + 1);  // float y = pos.y;  // v = new Vector2(x, y);  //}  //else  //{  // float x = pos.x - cellSize.x * (columnCount - index - 1) - cellOffset.x * (columnCount - index - 1);  // float y = pos.y - cellSize.y - cellOffset.y;  // v = new Vector2(x, y);  //}  //Debug.LogError("++++++++++++++ " + pos+ "     "+ v);  rect.anchoredPosition = v;  rect.SetAsFirstSibling(); }   // 鼠標上滑時,顯示當前cell的數據。同時記錄數據段的序號遞增。 void ShowRestCellData(Image cell, int index) {  if (TailNum< data.Count-1)  {   Debug.LogError("當前的序號是::::" + TailNum);   TailNum++;   HeadNum++;   cell.sprite = data[TailNum];  } }  void ShowPreviousCellData(Image cell, int index) {  if (HeadNum > 0)  {   Debug.LogError("當前的序號是::::" + HeadNum);   TailNum--;   HeadNum--;   cell.sprite = data[HeadNum];  } }   // 輪換的函數。每次亂換一行的cell。 void LoopScrolView(List<Sprite> data) {  SetContentSize(0, 1);  loopCount++;  RectTransform rect2 = content.GetChild(content.childCount - 1).GetComponent<RectTransform>();  for (int i = 0; i < columnCount; i++)  {   GameObject obj = F_cellQuee.Dequeue() as GameObject;   RectTransform rect = obj.GetComponent<RectTransform>();   ShowRestCellData(obj.GetComponent<Image>(), i);   SetBottomCellPosition(i, rect, rect2.anchoredPosition);   F_cellQuee.Enqueue(obj);  } } }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武功县| 怀柔区| 隆回县| 读书| 仁寿县| 阿克| 吉木萨尔县| 高碑店市| 甘洛县| 合阳县| 佛教| 彝良县| 武山县| 临清市| 大连市| 伊春市| 保定市| 集贤县| 南部县| 太谷县| 永康市| 元阳县| 昌江| 仪征市| 榆林市| 印江| 江西省| 富蕴县| 游戏| 清徐县| 永宁县| 桐梓县| 封丘县| 鄢陵县| 仙桃市| 昭觉县| 玛沁县| 房产| 新竹市| 马关县| 灵川县|