/// 创建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); }