列表在游戏开发中是比较常用的功能,unity自带的列表组件,随着数量的增多,它所占用的内存和DrawCall也会相应的增多,所以列表的重复循环利用变得至关重要,废话不多说,直接上代码。
1、列表组件自带的Mask替换成RectMask2D,可以减少相当多的DrawCall,unity也有相应的工具可以很直观的看出效果。
2、最重要的重复可利用列表:就拿上下滑动列表举例说明原理:每当滑动的距离超过一个列表的高度时候,就把超过的列表放到Content子物体的顶部或者底部,并刷新所有的列表信息。代码如下:注册监听列表组件滑动事件。
private void OnHandleValueChange( Vector2 vec )
{
UpdateListView();
}
private void UpdateListView()
{
scrollTrans.GetLocalCorners( rectCorners );
RectTransform firstTrans = contentTrans.GetChild( 0 ) as RectTransform;
firstTrans.GetWorldCorners( childCorners );
Vector3 pos1 = scrollTrans.InverseTransformPoint( childCorners[0] );
Vector3 pos2 = scrollTrans.InverseTransformPoint( childCorners[1] );
if( scrollType == ScrollType.BottomToTop )
{
if( pos1.y > rectCorners[1].y )
{
if( startIndex >= totalCount )
{
return;
}
startIndex++;
RectTransform lastTrans = contentTrans.GetChild( contentTrans.childCount - 1 ) as RectTransform;
firstTrans.SetAsLastSibling();
firstTrans.anchoredPosition = lastTrans.anchoredPosition + Vector2.down * itemPadding;
contentTrans.sizeDelta += Vector2.up * itemPadding;
moveCallBack?.Invoke( contentTrans, startIndex );
return;
}
if( pos2.y < rectCorners[1].y )
{
float height = contentTrans.sizeDelta.y - itemPadding;
if( height < initHeight )
{
return;
}
--startIndex;
RectTransform lastTrans = contentTrans.GetChild( contentTrans.childCount - 1 ) as RectTransform;
lastTrans.SetAsFirstSibling();
lastTrans.anchoredPosition = firstTrans.anchoredPosition + Vector2.up * itemPadding;
contentTrans.sizeDelta += Vector2.down * itemPadding;
moveCallBack?.Invoke( contentTrans, startIndex );
return;
}
}
}
这里仅贴出了主要的代码,
private void OnHandleItemMove( Transform trans, int index )
{
int childLength = trans.childCount;
for( int i = 0; i < childLength; i++ )
{
Transform childTrans = trans.GetChild( i );
if( null == itemArr[i] )
{
itemArr[i] = new SongItem( childTrans, index + i, OnHandleItemClick );
}
else
{
itemArr[i].RefreshItem( childTrans, index + i, OnHandleItemClick );
}
}
}
这里是对列表信息刷新的函数。
当然也可以扩展为从上到下、从下到上、从左到右、从右到左的滚动,源码后续会贴出。