码迷,mamicode.com
首页 > 其他好文 > 详细

[UGUI]ListLayoutGroup--可重用的滚动列表

时间:2017-02-12 18:44:53      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:产生   code   index   isp   public   重用   修改   例子   border   

为了不生成太多的GameObject,当滚动的时候,需要将出框的item重复利用起来。这个网上已经有了很多例子。我为了项目使用方便,在GridLayoutGroup基础上修改了一下,配合ScrollRect使用

技术分享

首先在传入数据的时候,需要知道要显示多少数据,为了拖动时看不到突然消失的item,会多显示一个(往前滑动的时候和往后滑动的时候会放在最前面或最后面):

    private float GetScrollRectSize()
    {
        var rectSize = m_scrollRect.GetComponent<RectTransform> ().rect.size;
        return m_Constraint = IsVertical ? rectSize.y : rect.y;
    }
    private float GetCellSize()
    {
        return m_Constraint = IsVertical ? cellSize.y + spacing.y : cellSize.x + spacing.x;
    }
    public void SetData<P, D>(ICollection<D> dataList, System.Action<int, P, D> setContentHandler)
        where P : MonoBehaviour
    {
        ........
        displayListCount = Mathf.CeilToInt(GetScrollRectSize () / GetCellSize()) + 1;
        .......
    }

 

在滚动的时候,首先需要知道最左上角的数据index:

    public int GetStartIndex()
    {
        if (m_dataList == null || m_dataList.Count == 0)
            return 0;
        float anchorPosition = IsVertical ? rectTransform.anchoredPosition.y : rectTransform.anchoredPosition.x;
        if(!IsVertical)
            anchorPosition *= -1;
        anchorPosition -=  GetCellSize() * 0.5f - GetPadding();
        return (int)(anchorPosition / GetCellSize()) * constraintCount;
    }

 

为了不产生其他开销,Item的实际顺序不会改动,这就需要在已有的顺序中对其在数据中的实际顺序做映射,举个例子,如果一屏可以显示四个数据,那么对应不同的startIndex,四个item的映射关系如下:

Start Index Actual Index
0 0 1 2 3
1 4 1 2 3
2 4 5 1 2

 

 

 

 

如下公式可得到Actual Index(对于无限滚动的列表,start index可能小于0):

    private  int GetActualIndex(int startIndex, int index)
    {
        var count = GetChildCount;
        return ((startIndex + (startIndex >= 0 ? (count - index - 1) : -index)) / count * count + index);
    }

 

滚动时,可根据Actual Index设置Item的位置,并对比滚动前的Actual Index是否改变,决定是否更新数据:

    private void SetCellsAlongAxis (int axis)
    {
        ......
        for(int i = 0; i < m_childCount; ++i) 
        {
            var child = m_childList[i];
                        ...
            if (IsVertical) {
                positionX = Mathf.Abs(actualIndex) % cellsPerMainAxis;
                positionY = actualIndex / cellsPerMainAxis;
            } else {
                positionX = actualIndex / cellsPerMainAxis;
                positionY = Mathf.Abs(actualIndex) % cellsPerMainAxis;
            }

            if (cornerX == 1)
                positionX = actualCellCountX - 1 - positionX;
            if (cornerY == 1)
                positionY = actualCellCountY - 1 - positionY;
            
......
if(actualIndex != previousIndex) { SetItemContent(acutalIndex, child, m_dataList[i]); } SetChildAlongAxis (child, 0, startOffset.x + (cellSize [0] + spacing [0]) * positionX, cellSize [0]); SetChildAlongAxis (child, 1, startOffset.y + (cellSize [1] + spacing [1]) * positionY, cellSize [1]); }
    }

 

[UGUI]ListLayoutGroup--可重用的滚动列表

标签:产生   code   index   isp   public   重用   修改   例子   border   

原文地址:http://www.cnblogs.com/drashnane/p/6391435.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!