/// 创建Element
        protected UIListViewItem CreateElement(int index, ref stRect rect)
        {
            UIListViewItem elementScript = null;

            //找
            if (m_unUsedElementScripts.Count > 0)
            {
                elementScript = m_unUsedElementScripts[0];
                m_unUsedElementScripts.RemoveAt(0);
            }
            else if (m_elementTemplate != null)
            {
                //克隆
                GameObject elementObject = Instantiate(m_elementTemplate);
                elementObject.transform.SetParent(m_content.transform);
                elementObject.transform.localScale = Vector3.one;
                //初始化
                InitializeComponent(elementObject);
                //
                elementScript = elementObject.GetComponent <UIListViewItem>();
            }

            if (elementScript != null)
            {
                elementScript.Enable(this, index, m_elementName, ref rect, IsSelectedIndex(index));
                m_elementScripts.Add(elementScript);
                //JW.Common.Log.LogD("Dispatch Element On Create Event, index = " + index);
                if (OnEnableItemHandler != null)
                {
                    OnEnableItemHandler(elementScript);
                }
            }

            return(elementScript);
        }
        /// 设置在Content上的位置
        public void SetRect(ref stRect rect)
        {
            m_rect = rect;
            RectTransform rectTransform = gameObject.transform as RectTransform;

            rectTransform.sizeDelta          = new Vector2(m_rect.m_width, m_rect.m_height);
            rectTransform.anchoredPosition   = new Vector2(rect.m_left, rect.m_top);
            rectTransform.anchoredPosition3D = new Vector3(rect.m_left, rect.m_top, 0);
        }
        /// 某项元素是否在滚动区域内(是否可见)
        public bool IsElementInScrollArea(int index)
        {
            if (index < 0 || index >= m_elementAmount)
            {
                return(false);
            }
            stRect rect = (m_useOptimized) ? m_elementsRect[index] : m_elementScripts[index].m_rect;

            return(IsRectInScrollArea(ref rect));
        }
        /// 处理元素
        protected virtual void ProcessElements()
        {
            m_contentSize = Vector2.zero;
            Vector2 offset = Vector2.zero;

            if (m_listType == UIListViewType.Vertical || m_listType == UIListViewType.VerticalGrid)
            {
                offset.y += m_elementLayoutOffset;
            }
            else
            {
                offset.x += m_elementLayoutOffset;
            }

            for (int i = 0; i < m_elementAmount; i++)
            {
                //Element布局
                stRect rect = LayoutElement(i, ref m_contentSize, ref offset);
                //记录Element Rect
                if (m_useOptimized)
                {
                    if (i < m_elementsRect.Count)
                    {
                        m_elementsRect[i] = rect;
                    }
                    else
                    {
                        m_elementsRect.Add(rect);
                    }
                }

                if (!m_useOptimized || IsRectInScrollArea(ref rect))
                {
                    CreateElement(i, ref rect);
                }
            }

            //设置extraContent if exist
            if (m_extraContent != null)
            {
                if (m_elementAmount > 0)
                {
                    ProcessExtraContent(ref m_contentSize, offset);
                }
                else
                {
                    m_extraContent.SetActive(false);
                }
            }
            //设置内容区域大小
            ResizeContent(ref m_contentSize, false);
        }
        /// 将某项元素移动到滚动区域内(使其可见)
        public void MoveElementInScrollArea(int index, bool moveImmediately)
        {
            if (index < 0 || index >= m_elementAmount)
            {
                return;
            }

            Vector2 fixedOffset = Vector2.zero;
            Vector2 position    = Vector2.zero;

            stRect rect = (m_useOptimized) ? m_elementsRect[index] : m_elementScripts[index].m_rect;

            position.x = m_contentRectTransform.anchoredPosition.x + rect.m_left;
            position.y = m_contentRectTransform.anchoredPosition.y + rect.m_top;

            if (position.x < 0)
            {
                fixedOffset.x = -position.x;
            }
            else if (position.x + rect.m_width > m_scrollAreaSize.x)
            {
                fixedOffset.x = m_scrollAreaSize.x - (position.x + rect.m_width);
            }

            if (position.y > 0)
            {
                fixedOffset.y = -position.y;
            }
            else if (position.y - rect.m_height < -m_scrollAreaSize.y)
            {
                fixedOffset.y = -m_scrollAreaSize.y - (position.y - rect.m_height);
            }

            if (moveImmediately)
            {
                m_contentRectTransform.anchoredPosition += fixedOffset;
            }
            else
            {
                Vector2 contentTargetAnchoredPosition = m_contentRectTransform.anchoredPosition + fixedOffset;
                //动画
                DOTween.To(() => { return(m_contentRectTransform.anchoredPosition); },
                           pos => { m_contentRectTransform.anchoredPosition = pos; },
                           contentTargetAnchoredPosition,
                           m_fSpeed);
            }
        }
        /// rect是否位于滚动可视区域
        protected bool IsRectInScrollArea(ref stRect rect)
        {
            Vector2 position = Vector2.zero;

            position.x = m_contentRectTransform.anchoredPosition.x + rect.m_left;
            position.y = m_contentRectTransform.anchoredPosition.y + rect.m_top;

            if (position.x + rect.m_width < 0 ||
                position.x > m_scrollAreaSize.x ||
                position.y - rect.m_height > 0 ||
                position.y < -m_scrollAreaSize.y
                )
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
        /// 处理元素滚动(优化模式)
        protected void UpdateElementsScroll()
        {
            //回收显示区域以外的Element
            for (int i = 0; i < m_elementScripts.Count;)
            {
                if (!IsRectInScrollArea(ref m_elementScripts[i].m_rect))
                {
                    RecycleElement(m_elementScripts[i], true);
                    continue;
                }

                i++;
            }

            //展示显示区域以内的Element
            for (int i = 0; i < m_elementAmount; i++)
            {
                stRect rect = m_elementsRect[i];

                if (IsRectInScrollArea(ref rect))
                {
                    bool exist = false;

                    for (int j = 0; j < m_elementScripts.Count; j++)
                    {
                        if (m_elementScripts[j].m_index == i)
                        {
                            exist = true;
                            break;
                        }
                    }

                    if (!exist)
                    {
                        CreateElement(i, ref rect);
                    }
                }
            }
        }
        /// Enable元素
        public void Enable(UIListView belongedList, int index, string name, ref stRect rect, bool selected)
        {
            m_belongedListScript = belongedList;
            m_index = index;
            //
            gameObject.name = name + "_" + index.ToString();

            if (m_useSetActiveForDisplay)
            {
                gameObject.ExtSetActive(true);
            }
            else
            {
                m_canvasGroup.alpha          = 1f;
                m_canvasGroup.blocksRaycasts = true;
            }
            //递归设置从属List
            SetComponentBelongedList(gameObject);
            //设置位置属性
            SetRect(ref rect);
            //设置选中/非选中外观
            ChangeDisplay(selected);
        }
        /// 计算元素布局
        protected stRect LayoutElement(int index, ref Vector2 contentSize, ref Vector2 offset)
        {
            stRect rect = new stRect();

            rect.m_width  = (int)((m_elementsSize == null || m_listType == UIListViewType.Vertical || m_listType == UIListViewType.VerticalGrid || m_listType == UIListViewType.HorizontalGrid) ? m_elementDefaultSize.x : m_elementsSize[index].x);
            rect.m_height = (int)((m_elementsSize == null || m_listType == UIListViewType.Horizontal || m_listType == UIListViewType.VerticalGrid || m_listType == UIListViewType.HorizontalGrid) ? m_elementDefaultSize.y : m_elementsSize[index].y);
            rect.m_left   = (int)offset.x;
            rect.m_top    = (int)offset.y;
            rect.m_right  = rect.m_left + rect.m_width;
            rect.m_bottom = rect.m_top - rect.m_height;
            rect.m_center = new Vector2(rect.m_left + rect.m_width * 0.5f, rect.m_top - rect.m_height * 0.5f);

            if (rect.m_right > contentSize.x)
            {
                contentSize.x = rect.m_right;
            }

            if (-rect.m_bottom > contentSize.y)
            {
                contentSize.y = -rect.m_bottom;
            }

            switch (m_listType)
            {
            case UIListViewType.Vertical:
            {
                offset.y -= (rect.m_height + m_elementSpacing.y);
            }
            break;

            case UIListViewType.Horizontal:
            {
                offset.x += (rect.m_width + m_elementSpacing.x);
            }
            break;

            case UIListViewType.VerticalGrid:
            {
                offset.x += (rect.m_width + m_elementSpacing.x);

                if (offset.x + rect.m_width > m_scrollAreaSize.x)
                {
                    offset.x  = 0;
                    offset.y -= (rect.m_height + m_elementSpacing.y);
                }
            }
            break;

            case UIListViewType.HorizontalGrid:
            {
                offset.y -= (rect.m_height + m_elementSpacing.y);

                if (-offset.y + rect.m_height > m_scrollAreaSize.y)
                {
                    offset.y  = 0;
                    offset.x += (rect.m_width + m_elementSpacing.x);
                }
            }
            break;
            }

            return(rect);
        }