FishPlayer

一个喜欢摸鱼的废物

0%

Unity UGUI 简单循环滚动列表

之前做了一个自带简单 GridLayout 的循环滚动列表。但是基于继承的思路做的。导师指出了其不便使用的一些情况,而且Unity其实是比较提倡大家使用组合模式的,所以我决定修改一下。

循环滚动

思路

因为交互侧没有无限滚动的需求,所以我打算直接用简单明确的思路做一个简单凑合能跑的版本。

首先根据视口大小计算出实际需要使用到的 GridElement 数量,通过比较灵活的接口去申请/释放 GridElement 物体(老实说我感觉我没有特别好的方法去计算一个准确的值。所以就按着 (row + 2) (column 2) 来计算了,虽然有一点浪费内存,但在我当前设置的滚动速度下是够用的。)。

再着,这个做法之所以很简单,是因为我无需做滚动相关的输入处理。这个方案需要与 UGUI ScrollRect 一同使用。
我会根据数据量计算并应用content的大小,这样就能够让 ScrollRect 照常处理滚动。

当每一次 ScrollRect 的滚动位置处理完毕后,先用 Viewport 的测试出能显示的 GridElement 物体,然后才根据 Content 位置来拜访 GridElement,并发出通知告知 GridElement 对应的数据序列号变更.

这个做法非常的简单易懂,但也有个明显的缺点,就是当位置变更时我需要根据数据量去频繁测试每个数据对应 GridElement 的可见性,感觉优一点的做法应该是缓存了当前可见的数据范围,再根据每次移动的距离来决定是做少量测试或是大量测试。

配合实际显示组件使用

我定义了一个简单的接口用于描述什么样的列表逻辑便于使用这个滚动列表。
但其实直接继承滚动列表也是一种可行的做法。

1
2
3
4
5
6
7
8
9
10

public interface IListView
{
int DataElementCount { get; }
RectTransform AddElement(RectTransform parent);
void RemoveElement(RectTransform element);
void InitElement(RectTransform element, int index);
void UnInitElement(RectTransform element);
void OnElementIndexChanged(RectTransform element, int prevIndex, int nextIndex);
}

总结

其实这个功能丢尽项目里后用的地方不是特别多,所以都是隔几个月修一下,每次都要看自己写的垃圾代码好久,属实头痛了。
总算是用起来比以前方便不少了。接下来就把一些小问题修一修好了。

回头再看已经和自己做的那个初版完全不一样了,个人认为思路比以前那个好多了。

完整代码