动态滚动列表

发布时间:2019-04-28 14:22

此博客文章最初发布于:http://emi.gd/blog/scrolled-list-dynamic/。

在前面的基本滚动列表中,我列出了一些涉及的能问题。今天,我将提出一个更强大的解决方案,我们在塔巴斯科提出了这个解决方案。我们很高兴使用列表的基本版本,直到我们开始为Kickerinho World开展活动。该活动包括许多…许多不同的级别(此时超过600),以滚动列表的形式显示。事实证明,滚动如此庞大的容器元素对游戏的UI能有很大的影响。 FPS下降率是不可接受的,因此我们不得不考虑更复杂的解决方案。力学的概念

这个想法很简单–我们不想在每次更新时渲染所有元素,我们只需要可见的元素。因此,当用户滚动我们的列表时,我们需要隐藏顶部的元素并显示底部的元素。为了能够做到这一点,我们必须计算窗口中可以容纳多少项,然后对ScrollRect发出的信号进行反应。以下gif显示了我们的脚本:

基地不要担心,你不必把早先创建的列表扔进垃圾桶–我们新的将继承它。必须重写AddElement和ClearPanel方法,因为它们只需要对可见的元素集进行作,而无需修改原始数据。

<图>
  protected override void AddElement(TData element){_elements.Add(元件);UpdateContainerSize();}public override void ClearPanel(){removeAllChildren()删除;_elements.Clear();}  

我们还需要在元素数量增加时调整容器大小的方法:

<图>
  protected void UpdateContainerSize(){float height = _elements.Count * _childHeigth;RectTransform rt = _container.GetComponent&lt; RectTransform&gt;();rt.sizeDelta = new Vector2(rt.sizeDelta.x,height);UpdateChildren();}  Init方法

在我们的名单生活的乞讨中,我们必须做一些准备。首先,我们将调用基类的Init方法,这将允许我们检查容器是否符合我们的期望。它必须关闭垂直拉伸,否则我们无确确定元素大小。然后我们需要做一些缓存&ndash;请记住,所有需要查看组件的东西(使用GetComponent方法)都应谨慎执行。我们将缓存元素和容器大小,这允许计算适合屏幕的项目数。另外,_elements列表被创建&ndash;它将代表当前在屏幕上可见的数据部分。我们还为ScrollRect&ndash的onValueChanged事件添加了一个。这将告诉我们是时候玩这些元素了。

<图>
  public override void Init(){if(!IsInitialized){base.Init();Debug.Assert(_containerTransform.anchorMax.y == _containerTransform.anchorMin.y,“ScrollListPooled:必须关闭垂直拉伸!”+ GetType());_elements = new List&lt; TData&gt;();var childTrans = _listElementCache.GetComponent&lt; RectTransform&gt;();_childWidth = childTrans.rect.width;_江山1.76childHeigth = childTrans.rect.height;if(_transformCache.childCount&gt; 0&amp;&amp; _childHeigth&gt; 0){RectTransform rt = _transformCache.GetChild(0).GetComponent&lt; RectTransform&gt;();_height = rt.rect.height;_count = Mathf.CeilToInt(_height / _childHeigth);}GetComponent&lt; ScrollRect&gt;()。onValueChanged.AddListener((v)=&gt; UpdateChildren());}}  更新孩子

对滚动作做出反应的方法称为UpdateChildren。要确定应该可见的元素的索引,我们使用anchoredPosition属的Y坐标。此属告诉我们容器的RectTransform相对于锚点的位置。

<图>
 public void UpdateChildren(){UpdateChildren(_containerTransform.anchoredPosition.y);}public void UpdateChildren(float scrolledY){int newFirst = Mathf.Clamp(Mathf.CeilToInt(scrolledY / _childHeigth) -  1,0,_elements.Count  -  1);int newLast = Mathf.Clamp(Mathf.Cei

lToInt(scrolledY / _childHeigth)+ _count,

此博客文章最初发布于:http://emi.gd/blog/scrolled-list-dynamic/。

在前面的基本滚动列表中,我列出了一些涉及的能问题。今天,我将提出一个更强大的解决方案,我们在塔巴斯科提出了这个解决方案。我们很高兴使用列表的基本版本,直到我们开始为Kickerinho World开展活动。该活动包括许多&hellip;许多不同的级别(此时超过600),以滚动列表的形式显示。事实证明,滚动如此庞大的容器元素对游戏的UI能有很大的影响。 FPS下降率是不可接受的,因此我们不得不考虑更复杂的解决方案。力学的概念

这个想法很简单&ndash;我们不想在每次更新时渲染所有元素,我们只需要可见的元素。因此,当用户滚动我们的列表时,我们需要隐藏顶部的元素并显示底部的元素。为了能够做到这一点,我们必须计算窗口中可以容纳多少项,然后对ScrollRect发出的信号进行反应。以下gif显示了我们的脚本:

基地不要担心,你不必把早先创建的列表扔进垃圾桶&ndash;我们新的将继承它。必须重写AddElement和ClearPanel方法,因为它们只需要对可见的元素集进行作,而无需修改原始数据。

<图>
  protected override void AddElement(TData element){_elements.Add(元件);UpdateContainerSize();}public override void ClearPanel(){removeAllChildren()删除;_elements.Clear();}  

我们还需要在元素数量增加时调整容器大小的方法:

<图>
  protected void UpdateContainerSize(){float height = _eleme1.76版本私服nts.Count * _childHeigth;RectTransform rt = _container.GetComponent&lt; RectTransform&gt;();rt.sizeDelta = new Vector2(rt.sizeDelta.x,height);UpdateChildren();}  Init方法

在我们的名单生活的乞讨中,我们必须做一些准备。首先,我们将调用基类的Init方法,这将允许我们检查容器是否符合我们的期望。它必须关闭垂直拉伸,否则我们无确确定元素大小。然后我们需要做一些缓存&ndash;请记住,所有需要查看组件的东西(使用GetComponent方法)都应谨慎执行。我们将缓存元素和容器大小,这允许计算适合屏幕的项目数。另外,_elements列表被创建&ndash;它将代表当前在屏幕上可见的数据部分。我们还为ScrollRect&ndash的onValueChanged事件添加了一个。这将告诉我们是时候玩这些元素了。

<图>
  public override void Init(){if(!IsInitialized){base.Init();Debug.Assert(_containerTransform.anchorMax.y == _containerTransform.anchorMin.y,“ScrollListPooled:必须关闭垂直拉伸!”+ GetType());_elements = new List&lt; TData&gt;();var childTrans = _listElementCache.GetComponent&lt; RectTransform&gt;();_childWidth = childTrans.rect.width;_childHeigth = childTrans.rect.height;if(_transformCache.childCount&gt; 0&amp;&amp; _childHeigth&gt; 0){RectTransform rt = _transformCache.GetChild(0).GetComponent&lt; RectTransform&gt;();_height = rt.rect.height;_count = Mathf.CeilToInt(_height / _childHeigth);}GetComponent&lt; ScrollRect&gt;()。onValueChanged.AddListener((v)=&gt; UpdateChildren());}}  更新孩子

对滚动作做出反应的方法称为UpdateChildren。要确定应该可见的元素的索引,我们使用anchoredPosition属的Y坐标。此属告诉我们容器的RectTransform相对于锚点的位置。

<图>
 public void UpdateChildren(){UpdateChildren(_containerTransform.anchoredPosition.y);}public void UpdateChildren(float scrolledY){int newFirst = Mathf.Clamp(Mathf.CeilToInt(scrolledY / _childHeigth) -  1,0,_elements.Count  - 

1);int newLast = Mathf.Clamp(Mathf.CeilToInt(scrolledY / _childHeigth)+ _count,

上一篇:MFORMA收购MobileGame Korea
下一篇:&#19968;&#20992;&#20256;&#22855;&#31169;