Пример #1
0
 public void Previous()
 {
     if (!CheckLength())
     {
         return;
     }
     Index--;
     if (Index < 0)
     {
         Index = _length - 1;
     }
     OnIndexChanged?.Invoke();
 }
Пример #2
0
 public void Next()
 {
     if (!CheckLength())
     {
         return;
     }
     Index++;
     if (Index > _length - 1)
     {
         Index = 0;
     }
     OnIndexChanged?.Invoke();
 }
Пример #3
0
 public void GoIndex(int index)
 {
     Index = index;
     for (int i = _blocks.Count - 1; i >= 0; i--)
     {
         _blocks[i].SetX(i < index ? 0 : (i + 1 - index) * _width);
     }
     OnIndexChanged?.Invoke(this, new IndexEventArgs(index, Count));
     if (Index < Count - 1)
     {
         return;
     }
     _addLast();
 }
    private void LateUpdate()
    {
        // 滞后删除
        if (m_NeedToRemove.Count > 0)
        {
            DelayDestroy();
        }

        if (m_Elements == null || m_Elements.Count == 0)
        {
            return;
        }

        if (m_Direction == Direction.Vertical)
        {
            var top    = m_Elements.First.Value;
            var bottom = m_Elements.Last.Value;

            while (IsElementShouldMoveUp(bottom.transform) && top.index > 0)
            {
                m_Elements.RemoveLast();
                m_Elements.AddFirst(bottom);
                Vector3 newPos = bottom.transform.localPosition;
                if (top.index % m_LineCount == 0)
                {
                    // 不在同一行:top在第一列,bottom的位置则应该是上一行的最后一个位置
                    newPos.x = top.transform.localPosition.x + (m_LineCount - 1) * GetCellAreaSize().x;
                    newPos.y = top.transform.localPosition.y + GetCellAreaSize().y;
                }
                else
                {
                    // 在同一行:bottom位于top的左侧
                    newPos.x = top.transform.localPosition.x - GetCellAreaSize().x;
                    newPos.y = top.transform.localPosition.y;
                }

                bottom.transform.localPosition = newPos;
                bottom.index = top.index - 1;
                OnIndexChanged.Invoke(bottom.index, bottom.transform);

                top    = m_Elements.First.Value;
                bottom = m_Elements.Last.Value;
            }

            while (IsElementShouldMoveDown(top.transform) && bottom.index < m_ObjectCount - 1)
            {
                m_Elements.RemoveFirst();
                m_Elements.AddLast(top);
                Vector3 newPos = top.transform.localPosition;
                if (bottom.index % m_LineCount == (m_LineCount - 1))
                {
                    // 不在同一行:bottom位于最后一列,则top位置应该是下一行的第一列
                    newPos.x = bottom.transform.localPosition.x - (m_LineCount - 1) * GetCellAreaSize().x;
                    newPos.y = bottom.transform.localPosition.y - GetCellAreaSize().y;
                }
                else
                {
                    // 在同一行:top位于bottom右侧
                    newPos.x = bottom.transform.localPosition.x + GetCellAreaSize().x;
                    newPos.y = bottom.transform.localPosition.y;
                }
                top.transform.localPosition = newPos;
                top.index = bottom.index + 1;
                OnIndexChanged.Invoke(top.index, top.transform);

                top    = m_Elements.First.Value;
                bottom = m_Elements.Last.Value;
            }
        }
        else
        {
            var left  = m_Elements.First.Value;
            var right = m_Elements.Last.Value;

            while (IsElementShouldMoveLeft(right.transform) && left.index > 0)
            {
                m_Elements.RemoveLast();
                m_Elements.AddFirst(right);
                Vector3 newPos = right.transform.localPosition;
                if (left.index % m_LineCount == 0)
                {
                    // 不在同一列:left位于第一行,则right位置应该是上一列的最后一行
                    newPos.x = left.transform.localPosition.x - GetCellAreaSize().x;
                    newPos.y = left.transform.localPosition.y - (m_LineCount - 1) * GetCellAreaSize().y;
                }
                else
                {
                    // 在同一列:right位于left的上方
                    newPos.x = left.transform.localPosition.x;
                    newPos.y = left.transform.localPosition.y + GetCellAreaSize().y;
                }
                right.transform.localPosition = newPos;
                right.index = left.index - 1;

                OnIndexChanged.Invoke(right.index, right.transform);

                left  = m_Elements.First.Value;
                right = m_Elements.Last.Value;
            }

            while (IsElementShouldMoveRight(left.transform) && right.index < m_ObjectCount - 1)
            {
                m_Elements.RemoveFirst();
                m_Elements.AddLast(left);
                Vector3 newPos = left.transform.localPosition;
                if (right.index % m_LineCount == (m_LineCount - 1))
                {
                    // 不在同一列:right位于最后一行,则left应该位于下一列的第一行
                    newPos.x = right.transform.localPosition.x + GetCellAreaSize().x;
                    newPos.y = right.transform.localPosition.y + (m_LineCount - 1) * GetCellAreaSize().y;
                }
                else
                {
                    // 在同一列:left位于right的下方
                    newPos.x = right.transform.localPosition.x;
                    newPos.y = right.transform.localPosition.y - GetCellAreaSize().y;
                }
                left.transform.localPosition = newPos;
                left.index = right.index + 1;

                OnIndexChanged.Invoke(left.index, left.transform);

                left  = m_Elements.First.Value;
                right = m_Elements.Last.Value;
            }
        }
    }
    private void CreateElements()
    {
        int elementCount = Mathf.Min(m_ObjectCount, CalculateElementsCount());

        m_Elements = new LinkedList <Element>();

        // 每行/每列最大元素的数量
        int eleCountPerLine = Mathf.CeilToInt((float)m_ObjectCount / m_LineCount);

        if (m_Direction == Direction.Vertical)
        {
            float contentHeight = GetCellAreaSize().y *eleCountPerLine + m_Padding.vertical;
            float contentWidth  = GetCellAreaSize().x *m_LineCount + m_Padding.horizontal;
            Content.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, contentWidth);
            Content.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, contentHeight);
        }
        else
        {
            float contentHeight = GetCellAreaSize().y *m_LineCount + m_Padding.vertical;
            float contentWidth  = GetCellAreaSize().x *eleCountPerLine + m_Padding.horizontal;
            Content.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, contentWidth);
            Content.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, contentHeight);
        }

        int childCount = rectChildren.Count;

        for (int i = 0; i < elementCount; i++)
        {
            RectTransform rt = null;
            if (i < childCount)
            {
                rt = this.rectTransform.GetChild(i) as RectTransform;
            }
            else if (m_ElementPrefab != null)
            {
                GameObject g = Instantiate(m_ElementPrefab, Content);
                rt = g.transform as RectTransform;
            }

            if (rt == null)
            {
                return;
            }

            // 沿着指定方向的索引数(水平-列索引、垂直-行索引)
            int r = Mathf.FloorToInt((float)i / m_LineCount);

            // 行内索引(水平-行索引、垂直-列索引)
            int c = i % m_LineCount;

            if (m_Direction == Direction.Horizontal)
            {
                Vector2 offset = new Vector2(GetStartOffset(0, GetCellAreaSize().x *eleCountPerLine), GetStartOffset(1, m_CellSize.y));
                SetChildAlongAxis(rt, 0, offset.x + GetCellAreaSize().x *r);
                SetChildAlongAxis(rt, 1, offset.y + GetCellAreaSize().y *c);
            }
            else
            {
                Vector2 offset = new Vector2(GetStartOffset(0, m_CellSize.x), GetStartOffset(1, GetCellAreaSize().y *eleCountPerLine));
                SetChildAlongAxis(rt, 0, offset.x + GetCellAreaSize().x *c);
                SetChildAlongAxis(rt, 1, offset.y + GetCellAreaSize().y *r);
            }

            m_Elements.AddLast(new Element()
            {
                index     = i,
                transform = rt
            });
        }

        // Fix : 修复子物体数量大于所需数量时,删除多余部分
        // 滞后删除,在 Rebuild 阶段不允许删除对象
        for (int i = elementCount; i < childCount; i++)
        {
            RectTransform child = rectTransform.GetChild(i) as RectTransform;
            if (child == null)
            {
                continue;
            }
            m_NeedToRemove.Add(child.gameObject);
        }

        var ele = m_Elements.First;

        while (ele != null)
        {
            OnIndexChanged.Invoke(ele.Value.index, ele.Value.transform);
            ele = ele.Next;
        }
    }