欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

UGUI實(shí)現(xiàn)ScrollView無限滾動(dòng)效果

 更新時(shí)間:2021年07月27日 10:34:04   作者:Tong1993222  
這篇文章主要為大家詳細(xì)介紹了UGUI實(shí)現(xiàn)ScrollView無限滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

content節(jié)點(diǎn)不添加任何組件。布局組件默認(rèn)是會(huì)重新排版子節(jié)點(diǎn)的,所以如果子節(jié)點(diǎn)的位置變化,會(huì)重新排版,不能達(dá)到效果。Size Fitter組件也不加,自己寫代碼調(diào)整Size大?。ú徽{(diào)整大小,無法滑動(dòng))。

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

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

下面是完整代碼:

public class UIScrollViewTest : MonoBehaviour {
 
 public RectTransform content;
 public GameObject cell;
 // cell的初始化個(gè)數(shù)
 public int cellAmount = 0;
 // 鼠標(biāo)上滑時(shí),存儲(chǔ)Cell的Queue。正序存儲(chǔ)
 public Queue F_cellQuee = new Queue();
 // 鼠標(biāo)下滑時(shí),存儲(chǔ)Cell的Queue。到序存儲(chǔ)
 public Queue B_cellQuee = new Queue();
 // cell的Size
 public Vector2 cellSize = new Vector2(100,100);
 // cell的間隔
 public Vector2 cellOffset = new Vector2(0,0);
 // 列數(shù)
 public int columnCount = 0;
 private int rowCount;
 // 上一次content的位置
 public float lastPos;
 // 滾動(dòng)的次數(shù)
 public int loopCount = 0;
 // cell顯示的數(shù)據(jù)段的開頭和結(jié)尾序號(hào)
 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("行數(shù)是:::" + rowCount);
 
  //Debug.LogError("+++++++++++++++++ " + (5>>3));
 }
 
 
 void Update()
 {
  // 觸發(fā)滾動(dòng)。
  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();
   // 顯示默認(rèn)的數(shù)據(jù)
   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);
  }
 
  // 計(jì)算行數(shù)
  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的行數(shù)基礎(chǔ)上,向下多出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));
  }
 }
 
 // 計(jì)算頂部的Cell輪換到底部時(shí)的位置。以當(dāng)前最后一行的最后一個(gè)Cell的位置為基準(zhǔn)計(jì)算。
 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);
  }
  // 出現(xiàn)不滿行的情況。例如數(shù)據(jù)有103個(gè),可以用23個(gè)cell來輪換。這樣就會(huì)出現(xiàn)不滿行的情況。
  // 這種情況下是頂部的一行cell順次接到底部不滿的行。例如23號(hào)cell后面接1號(hào)和2號(hào)cell,3號(hào)和4號(hào)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();
 }
 
 // 計(jì)算底部的cell輪換到頂部是的位置,基準(zhǔn)位置是當(dāng)前行的第一個(gè)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();
 }
 
 
 // 鼠標(biāo)上滑時(shí),顯示當(dāng)前cell的數(shù)據(jù)。同時(shí)記錄數(shù)據(jù)段的序號(hào)遞增。
 void ShowRestCellData(Image cell, int index)
 {
  if (TailNum< data.Count-1)
  {
   Debug.LogError("當(dāng)前的序號(hào)是::::" + TailNum);
   TailNum++;
   HeadNum++;
   cell.sprite = data[TailNum];
  }
 }
 
 void ShowPreviousCellData(Image cell, int index)
 {
  if (HeadNum > 0)
  {
   Debug.LogError("當(dāng)前的序號(hào)是::::" + HeadNum);
   TailNum--;
   HeadNum--;
   cell.sprite = data[HeadNum];
  }
 }
 
 
 // 輪換的函數(shù)。每次亂換一行的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);
  }
 }
 
}

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#Process的OutputDataReceived事件不觸發(fā)問題及解決

    C#Process的OutputDataReceived事件不觸發(fā)問題及解決

    這篇文章主要介紹了C#Process的OutputDataReceived事件不觸發(fā)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C#實(shí)現(xiàn)的MD5加密功能與用法示例

    C#實(shí)現(xiàn)的MD5加密功能與用法示例

    這篇文章主要介紹了C#實(shí)現(xiàn)的MD5加密功能與用法,結(jié)合實(shí)例形式分析了C# MD5加密類的定義與使用方法,需要的朋友可以參考下
    2017-01-01
  • UGUI繪制動(dòng)態(tài)曲線

    UGUI繪制動(dòng)態(tài)曲線

    這篇文章主要為大家詳細(xì)介紹了UGUI繪制動(dòng)態(tài)曲線的具體方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • C#開發(fā)Winform實(shí)現(xiàn)文件操作案例

    C#開發(fā)Winform實(shí)現(xiàn)文件操作案例

    這篇文章介紹了C#開發(fā)Winform實(shí)現(xiàn)文件操作的案例,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 解析在C#中接口和類的異同

    解析在C#中接口和類的異同

    今天小編就為大家分享一篇關(guān)于解析在C#中接口和類的異同,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 深入HTTP head的使用詳解

    深入HTTP head的使用詳解

    本篇文章是對(duì)HTTP head的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C#多線程編程詳解

    C#多線程編程詳解

    C#提供了豐富的多線程操作,為編程帶來了極大的便利,但如果使用不當(dāng)也會(huì)帶來各種各樣的麻煩。本篇文章主要介紹了C#多線程,有需要的可以了解一下。
    2016-11-11
  • C#獲取指定年份第一個(gè)星期一具體日期的方法

    C#獲取指定年份第一個(gè)星期一具體日期的方法

    這篇文章主要介紹了C#獲取指定年份第一個(gè)星期一具體日期的方法,涉及C#日期與字符串操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C# 異步多線程入門到精通之ThreadPool篇

    C# 異步多線程入門到精通之ThreadPool篇

    ThreadPool 是 .net 2.0 時(shí)代的產(chǎn)物,有了 Thread 為什么還會(huì)有 ThreadPool 呢?ThreadPool 可以做到限制線程數(shù)量、重用線程
    2021-11-11
  • C#實(shí)現(xiàn)二叉排序樹代碼實(shí)例

    C#實(shí)現(xiàn)二叉排序樹代碼實(shí)例

    今天小編就為大家分享一篇關(guān)于C#實(shí)現(xiàn)二叉排序樹代碼實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-10-10

最新評(píng)論