多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > NGUI UIScrollView - 大量item子項的性能優化

NGUI UIScrollView - 大量item子項的性能優化

來源:程序員人生   發布時間:2014-11-15 06:17:02 閱讀次數:3185次

1、當UIScrollView的下面的包括的子項太多(2310個之上)時,它的轉動就會變的很卡。

對些網上也有很多的優化它的相干,下面是我的1個優化:

1、將在超越裁剪框的1個item的距離的item,從scrollview中燒毀掉 。當它將要出現在裁剪框中時,再將它構造出來。-- 大家好你都是這么做的。

2、為避免頻繁的構造、燒毀,致使頻繁的分配內存和產生大量的內存垃圾內,致使的性能問題,我增加了1個對象池來管理item的構造與移除工作。

3、scrollvew中的元素在1般情況下,其中的item是要求等距的,如果它的大小不1樣,它們的距離就會良莠不齊。而這個問題在我的優化中是不存在的。

4、最主要是代碼量少、使用簡單、擴大方便。


2、話不多說,上代碼:

1、主類:Lzh_LoopScrollView.cs

/* * 描術: * * 作者:AnYuanLzh * 公司:lexun * 時間:2014-xx-xx */ using UnityEngine; using System.Collections.Generic; /// <summary> /// 這個類主要做了1件事,就是優化了,NGUI UIScrollView 在數據量很多都時候, /// 創建過量都GameObject對象,造成資源浪費. /// </summary> public class Lzh_LoopScrollView : MonoBehaviour { public enum ArrangeDirection { Left_to_Right, Right_to_Left, Up_to_Down, Down_to_Up, } /// <summary> /// items的排列方式 /// </summary> public ArrangeDirection arrangeDirection = ArrangeDirection.Up_to_Down; /// <summary> /// 列表單項模板 /// </summary> public GameObject itemPrefab; /// <summary> /// The items list. /// </summary> public List<Lzh_LoopItemObject> itemsList; /// <summary> /// The datas list. /// </summary> public List<Lzh_LoopItemData> datasList; /// <summary> /// 列表腳本 /// </summary> public UIScrollView scrollView; public GameObject itemParent; /// <summary> /// itemsList的第1個元素 /// </summary> Lzh_LoopItemObject firstItem; /// <summary> /// itemsList的最后1個元素 /// </summary> Lzh_LoopItemObject lastItem; public delegate void DelegateHandler(Lzh_LoopItemObject item, Lzh_LoopItemData data); /// <summary> /// 響應 /// </summary> public DelegateHandler OnItemInit; /// <summary> /// 第1item的起始位置 /// </summary> public Vector3 itemStartPos = Vector3.zero; /// <summary> /// 菜單項間隙 /// </summary> public float gapDis = 0f; // 對象池 // 再次優化,頻繁的創建與燒毀 Queue<Lzh_LoopItemObject> itemLoop = new Queue<Lzh_LoopItemObject>(); void Awake() { if(itemPrefab==null || scrollView==null || itemParent==null) { Debug.LogError("Lzh_LoopScrollView.Awake() 有屬性沒有在inspector中賦值"); } // 設置scrollview的movement if(arrangeDirection == ArrangeDirection.Up_to_Down || arrangeDirection == ArrangeDirection.Down_to_Up) { scrollView.movement = UIScrollView.Movement.Vertical; } else { scrollView.movement = UIScrollView.Movement.Horizontal; } } // Update is called once per frame void Update () { //if(scrollView.isDragging) { Validate(); } } /// <summary> /// 檢驗items的兩端是不是要補上或刪除 /// </summary> void Validate() { if( datasList==null || datasList.Count==0) { return; } // 如果itemsList還不存在 if(itemsList==null || itemsList.Count==0) { itemsList = new List<Lzh_LoopItemObject>(); Lzh_LoopItemObject item = GetItemFromLoop(); InitItem(item, 0, datasList[0]); firstItem = lastItem = item; itemsList.Add(item); //Validate(); } // bool all_invisible = true; foreach(Lzh_LoopItemObject item in itemsList) { if(item.widget.isVisible==true) { all_invisible=false; } } if (all_invisible == true) return; // 先判斷前端是不是要增減 if(firstItem.widget.isVisible) { // 判斷要不要在它的前面補充1個item if(firstItem.dataIndex>0) { Lzh_LoopItemObject item = GetItemFromLoop(); // 初化:數據索引、大小、位置、顯示 int index = firstItem.dataIndex⑴; //InitItem(item, index, datasList[index]); AddToFront(firstItem, item, index, datasList[index]); firstItem = item; itemsList.Insert(0,item); //Validate(); } } else { // 判斷要不要將它移除 // 條件:本身是不可見的;且它后1個item也是不可見的(或被被裁剪過半的). // 這有個隱含條件是itemsList.Count>=2. if(itemsList.Count>=2 && itemsList[0].widget.isVisible==false && itemsList[1].widget.isVisible==false) { itemsList.Remove(firstItem); PutItemToLoop(firstItem); firstItem = itemsList[0]; //Validate(); } } // 再判斷后端是不是要增減 if(lastItem.widget.isVisible) { // 判斷要不要在它的后面補充1個item if(lastItem.dataIndex < datasList.Count⑴) { Lzh_LoopItemObject item = GetItemFromLoop(); // 初化:數據索引、大小、位置、顯示 int index = lastItem.dataIndex+1; AddToBack(lastItem, item, index, datasList[index]); lastItem = item; itemsList.Add(item); //Validate(); } } else { // 判斷要不要將它移除 // 條件:本身是不可見的;且它前1個item也是不可見的(或被被裁剪過半的). // 這有個隱含條件是itemsList.Count>=2. if(itemsList.Count>=2 && itemsList[itemsList.Count⑴].widget.isVisible==false && itemsList[itemsList.Count⑵].widget.isVisible==false) { itemsList.Remove(lastItem); PutItemToLoop(lastItem); lastItem = itemsList[itemsList.Count⑴]; //Validate(); } } } /// <summary> /// Init the specified datas. /// </summary> /// <param name="datas">Datas.</param> public void Init(List<Lzh_LoopItemData> datas, DelegateHandler onItemInitCallback) { datasList = datas; this.OnItemInit = onItemInitCallback; Validate(); } /// <summary> /// 構造1個 item 對象 /// </summary> /// <returns>The item.</returns> Lzh_LoopItemObject CreateItem() { GameObject go = NGUITools.AddChild(itemParent,itemPrefab); UIWidget widget = go.GetComponent<UIWidget>(); Lzh_LoopItemObject item = new Lzh_LoopItemObject(); item.widget = widget; go.SetActive(true); return item; } /// <summary> /// 用數據列表來初始化scrollview /// </summary> /// <param name="item">Item.</param> /// <param name="indexData">Index data.</param> /// <param name="data">Data.</param> void InitItem(Lzh_LoopItemObject item, int dataIndex, Lzh_LoopItemData data) { item.dataIndex = dataIndex; if(OnItemInit!=null) { OnItemInit(item, data); } item.widget.transform.localPosition = itemStartPos; } /// <summary> /// 在itemsList前面補上1個item /// </summary> void AddToFront(Lzh_LoopItemObject priorItem, Lzh_LoopItemObject newItem, int newIndex, Lzh_LoopItemData newData) { InitItem (newItem, newIndex, newData); // 計算新item的位置 if(scrollView.movement == UIScrollView.Movement.Vertical) { float offsetY = priorItem.widget.height*0.5f + gapDis + newItem.widget.height*0.5f; if(arrangeDirection == ArrangeDirection.Down_to_Up) offsetY *=⑴f; newItem.widget.transform.localPosition = priorItem.widget.cachedTransform.localPosition + new Vector3(0f, offsetY, 0f); } else { float offsetX = priorItem.widget.width*0.5f + gapDis + newItem.widget.width*0.5f; if(arrangeDirection == ArrangeDirection.Right_to_Left) offsetX *=⑴f; newItem.widget.transform.localPosition = priorItem.widget.cachedTransform.localPosition - new Vector3(offsetX, 0f, 0f); } } /// <summary> /// 在itemsList后面補上1個item /// </summary> void AddToBack(Lzh_LoopItemObject backItem, Lzh_LoopItemObject newItem, int newIndex, Lzh_LoopItemData newData) { InitItem (newItem, newIndex, newData); // 計算新item的位置 if(scrollView.movement == UIScrollView.Movement.Vertical) { float offsetY = backItem.widget.height*0.5f + gapDis + newItem.widget.height*0.5f; if(arrangeDirection == ArrangeDirection.Down_to_Up) offsetY *=⑴f; newItem.widget.transform.localPosition = backItem.widget.cachedTransform.localPosition - new Vector3(0f, offsetY, 0f); } else { float offsetX = backItem.widget.width*0.5f + gapDis + newItem.widget.width*0.5f; if(arrangeDirection == ArrangeDirection.Right_to_Left) offsetX *=⑴f; newItem.widget.transform.localPosition = backItem.widget.cachedTransform.localPosition + new Vector3(offsetX, 0f, 0f); } } #region 對象池性能相干 /// <summary> /// 從對象池中取行1個item /// </summary> /// <returns>The item from loop.</returns> Lzh_LoopItemObject GetItemFromLoop() { Lzh_LoopItemObject item; if(itemLoop.Count<=0) { item = CreateItem(); } else { item = itemLoop.Dequeue(); } item.widget.gameObject.SetActive(true); return item; } /// <summary> /// 將要移除的item放入對象池中 /// --這個里我保證這個對象池中存在的對象不超過3個 /// </summary> /// <param name="item">Item.</param> void PutItemToLoop(Lzh_LoopItemObject item) { if(itemLoop.Count>=3) { Destroy(item.widget.gameObject); return; } item.dataIndex = ⑴; item.widget.gameObject.SetActive(false); itemLoop.Enqueue(item); } #endregion }



2、item對像的封裝類:Lzh_LoopItemObject,不要求具體的item類來繼承它,但我們要示具體的item對像1定要包括UIWidget組件。

/* * 描術: * * 作者:AnYuanLzh * 公司:lexun * 時間:2014-xx-xx */ using UnityEngine; using System.Collections; /// <summary> /// item對像的封裝類Lzh_LoopItemObject,不要求具體的item類來繼承它。 /// 但我們要示具體的item對像1定要包括UIWidget組件。 /// </summary> [System.Serializable] public class Lzh_LoopItemObject { /// <summary> /// The widget. /// </summary> public UIWidget widget; /// <summary> /// 本item,在實際全部scrollview中的索引位置, /// 即對就數據,在數據列表中的索引 /// </summary> public int dataIndex= ⑴; }



3、與item對關聯的數據類:Lzh_LoopItemData,具體的item的數據類1定繼承它

/* * 描術: * * 作者:AnYuanLzh * 公司:lexun * 時間:2014-xx-xx */ using UnityEngine; using System.Collections; /// <summary> /// 與item對關聯的數據類,具體的item的數據類1定繼承它 /// </summary> public class Lzh_LoopItemData { // *** }

4、上面3個是主要的類,注釋也比較詳細。

4、demo工程

具體的使用請下載我的demo工程

1、demo的運行效果圖:

              

2、demo下載:這個包中1份工程碼和1個build好的可運行的exe。

   (注:其代碼工程中缺少NGUI插件,而要你們自行加上,這個demo我用的是ngui3.7.4。我覺得相近的其它版ngui也是行的)


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产亚洲精品国产一区 | 丁香九月婷婷 | 久久国产精品亚洲一区二区 | 色a在线| 免费观看黄色的网站 | 亚洲品质自拍视频网站 | 在线播放亚洲美女视频网站 | 波多野结衣手机在线视频 | a视频在线 | 视频一区二区三区在线 | 毛色毛片免费看 | 国产成人综合手机在线播放 | 中文字幕免费在线视频 | 国产精品久久九九 | 国内自拍在线观看 | 欧美成人网在线综合视频 | japanese17一18sex日本护士 | 国产69精品久久 | 99久久综合狠狠综合久久aⅴ | 欧美xxxx性 | 午夜视频在线免费播放 | 国产尤物精品视频 | 欧美精品一区二区三区久久 | 国产欧美日韩综合一区二区三区 | 久久精品隔壁老王影院 | 伊人久久大香线蕉亚洲 | 国产免费资源高清小视频在线观看 | 亚洲第一成年网 | 自拍视频啪 | 婷婷亚洲国产成人精品性色 | 国产成人综合一区人人 | 国产午夜人做人免费视频中文 | 国产98在线 | 国产免费叼嘿网站免费 | 亚洲免费网站观看视频 | 欧美一级视频在线高清观看 | baoyu116.永久免费网站 | 最近2019中文字幕免费大全8 | 一区二区三区在线视频观看 | 欧美18videosex性欧美老师 | 久久久久欧美国产精品 |