UGUI(三)无限循环列表

时间:2023-01-30 07:40:34

循环列表其实是针对列表组件的优化,如果有1000条数据普通列表会创建1000个item,这样在打开或关闭界面时会有很明显的卡顿现象。所以趁现在有空就尝试做个demo。NGUI的例子中有循环列表的例子,但是要用到项目中还得琢磨一阵子,而且这种功能自己尝试写一写是很好的事情。

先上图:

UGUI(三)无限循环列表

图中显示到1000条数据的位置,但是注意红框中的item个数它只有11个,所以界面打开关闭也不会有明显的卡顿,原理并不复杂,当滑动条向下滑时,第一个超过显示区域时就移动到最下面;当滑动条向上滑时,最后一个超过显示区域就移动到最上面,然后从数据集合中取出数据进行显示,如此循环即可。

 

1.先看看封装之后逻辑层的使用

只需要传入【列表的最大数量】和【更新item的回调事件】这两个参数。

刷新界面的代码在封装界面时就可以很*的进行编写,嘿嘿,是不是超方便^_^?!

代码如下:

UGUI(三)无限循环列表

 

2.以下是列表的封装

初版代码如下(并不是十分完善只有垂直方向):

  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. using UnityEngine.UI;  
  5.   
  6. public delegate void UpdateListItem(Transform item, int index);  
  7. public class UIComUnList MonoBehaviour  
  8.   
  9.     // UI对象绑定  
  10.     public Transform m_itemParent;  
  11.     public GameObject m_item;  
  12.     public Scrollbar m_sb;  
  13.   
  14.     // 外部参数设置  
  15.     public int m_itemWidth;     //单元格宽  
  16.     public int m_itemHeight;    //单元格高  
  17.   
  18.     public int m_fixedColumnCount;  // 固定列数  
  19.     public int m_fixedColCount;     // 固定行数  
  20.   
  21.     // 内部私有遍历  
  22.     private Vector2 m_allItemArea Vector2.zero;  // 当前所有内容高度  
  23.     private Vector2 m_showArea Vector2.zero;     // 当前显示局域  
  24.   
  25.     // 前后的单元格位置  
  26.     private Vector2 m_firstItemPos Vector2.zero;  
  27.     private Vector2 m_lastItemPos Vector2.zero;  
  28.   
  29.     // 数据处理  
  30.     private int m_listMaxLength 0 
  31.     private int m_curShowStartIndex 0 
  32.     private int m_curShowEndIndex 0 
  33.   
  34.     // 更新item内容  
  35.     private UpdateListItem m_updateItem;  
  36.   
  37.     private float m_curSbVal 0//记录当前值用于获取滑动方向  
  38.     // 初始化  
  39.     public void Init(int maxLength, UpdateListItem updateItem)  
  40.      
  41.         m_showArea GetComponent().sizeDelta;  
  42.         m_item.SetActive(false);  
  43.         m_firstItemPos.y += m_itemHeight;  
  44.         m_curSbVal m_sb.value;  
  45.         m_curShowEndIndex m_fixedColCount;  
  46.   
  47.         m_listMaxLength maxLength;  
  48.         m_updateItem updateItem;  
  49.         for (int 0m_fixedColCount 1i++)  
  50.          
  51.             Transform item CreateItem(i);  
  52.             m_updateItem(item, i);  
  53.          
  54.      
  55.     // 创建item  
  56.     private Transform CreateItem(int index)  
  57.    
  58.         Transform item  
  59.             ((GameObject)GameObject.Instantiate(m_item)).transform;  
  60.         item.gameObject.SetActive(true);  
  61.         item.SetParent(m_itemParent);  
  62.   item.name index.ToString();  
  63.         // 1.行  
  64.         int row index m_fixedColumnCount;  
  65.         // 2.列  
  66.         int col index m_fixedColumnCount;  
  67.         item.localPosition new Vector3(col m_itemWidth, -1 row m_itemHeight, 0f);  
  68.   
  69.         m_allItemArea.y (row 1m_itemHeight;  
  70.         m_lastItemPos.y -1 (int)m_allItemArea.y;  
  71.         return item;  
  72.    
  73.   
  74.     // 滑动条值改变时调用  
  75.     public void OnDragSlider(float val)  
  76.      
  77.         UpdateListByFloat(m_sb.value (m_listMaxLength m_fixedColCount));  
  78.      
  79.     // 通过一个浮点值滑动列表  
  80.     public void UpdateListByFloat(float val)  
  81.      
  82.         UpdateListPos(val);  
  83.         if (val m_curSbVal)  
  84.          
  85.             if (m_curShowEndIndex >= m_listMaxLength 1return 
  86.             UpdateItemPos(true);  
  87.          
  88.         else  
  89.          
  90.             if (m_curShowStartIndex <= 0return 
  91.             UpdateItemPos(false);  
  92.          
  93.         m_curSbVal val;  
  94.      
  95.     // 更新item父节点位置  
  96.     private void UpdateListPos(float val)  
  97.      
  98.         // 获取多出来的高度  
  99.         float excess 0f;  
  100.         if (m_allItemArea.y m_showArea.y)  
  101.          
  102.             excess m_allItemArea.y m_showArea.y;  
  103.          
  104.         m_itemParent.localPosition new Vector2(0excess val);  
  105.      
  106.     // 更新item位置  
  107.     private void UpdateItemPos(bool isDown)  
  108.      
  109.         if (isDown)  // 下滑  
  110.          
  111.             for (int 0m_itemParent.childCount; i++)  
  112.              
  113.                 Transform item m_itemParent.GetChild(i);  
  114.                 float curPos item.localPosition.y m_itemParent.localPosition.y;  
  115.                 if (curPos m_itemHeight)  
  116.                  
  117.                     item.localPosition new Vector3(0m_lastItemPos.y, 0);  
  118.                     m_lastItemPos.y -= m_itemHeight;  
  119.                     m_firstItemPos.y -= m_itemHeight;  
  120.   
  121.                     m_updateItem(item, m_curShowEndIndex 1);  
  122.                     m_curShowStartIndex ++;  
  123.                     m_curShowEndIndex++;  
  124.                     //break;  
  125.                  
  126.              
  127.          
  128.         else  
  129.          
  130.             for (int m_itemParent.childCount 1>=0 i--)  
  131.              
  132.                 Transform item m_itemParent.GetChild(i);  
  133.                 float curPos item.localPosition.y m_itemParent.localPosition.y;  
  134.                 if (curPos -1 m_showArea.y)  
  135.                  
  136.                     item.localPosition new Vector3(0m_firstItemPos.y, 0);  
  137.                     m_firstItemPos.y += m_itemHeight;  
  138.                     m_lastItemPos.y += m_itemHeight;  
  139.   
  140.                     m_updateItem(item, m_curShowStartIndex 1);  
  141.                     m_curShowEndIndex --;  
  142.                     m_curShowStartIndex--;  
  143.                     //break;  
  144.                  
  145.              
  146.          
  147.      
  148. }

 

注:这种功能就算没有实现也不会成为游戏开发中的瓶颈,因为有很多方式可以避免数据量大引起卡顿的情况,比如使用分页,限制显示数量上限等。