动态可拖动列表DynmicList,ScrollView

虽然这是在2D ToolKit上实现的,但是下面会尽量写的通用一点。

所谓的DynamicList,指的是如果有一个Scrollview,里面的item太多。需要实例化很多个item且每帧需要处理每个item的数据。
这时候为了减少性能压力会做成一个循环的List,通过最后一个与第一个item的位置交换,只实例化比界面多一个的item来重复写需要的数据。
也就是说。有一百个数据。用十个item来实现。

这里先声明一下几个变量。
float _itemStride;     //每个item的宽
List<Data> _ItemDataList;      //item的数据list
List<Transform> _cachedContentItems;      //现在在使用的item(activeSelf == false)
List<Transform> _unusedContentItems;      //现在没使用的item (activeSelf == true)
int _firstCachedItem;      //第一个使用中的item
int maxVisiableItems;      //最多显示多少个item

一、
首先这里需要先确定一个数据:
这个ScrollView里需要实例化多少个Item

这里的基本思路就是。
一个item有多大
Scrollview这个框有多大。
除一下(除不尽的按大的算,如10.2算11)就知道这个框最多能放多少个item。
实际要比最多多一个所以最多的item数要+1

代码就是:

(tk2d不会算item的高...)


二、
实例化足够的item。放到Scrollview中,并摆放每个item的在合适的位置(计算间距,这个再NGUI里用UIGrid就可以了,tk2d需要自己计算)。
还需要用_unusedContentItems 来保存每个item方便之后控制。
这时每个item是没有数据的。数据需要用另一个list _ItemDataList 来维护。

这时候填充数据到_ItemDataList(还没到item)

接下来就是哪些该显示哪些不该显示,移动item置顶,填充数据到item的逻辑。
所以整个函数的逻辑就是
在滑动过程中是需要一直刷新UpdataListGraphics逻辑的。所以这里还需要
现在就能好好说下刚刚说的刷新逻辑了

三、
1.第一步 计算当前可见的第一个item的编号。
计算方法:
((总的item的大小(即content框的大小) - Scrollview大小(可视大小) )* 当前滑动的比例(0-1,滑到低端是1)) / itemStride(item高)
先算出上面部分的大小,再除于item高得。
代码如下:

2.第二步 如果item数量有增删时需要做的处理
简单来说就是重新计算content大小,把所有item setActive(false),都放到unusedlist里面。所有标志位重置。滑动恢复到之前的位置。
这里有个关键。可以看到这里的ContentLength的大小是计算所有item数据乘以他们的高,也就是说100个数据,10个item的话,这里是乘以100

 接着在算一下最后一个item的编号。

第三步、把多出的隐藏掉
分两种情况:
1.往上拉时最上的item出了显示框可以关掉。(firstCacheditem <  firstVisiableItem根据刚刚计算出来的第一个可显示item)
最上面的item维护的值firstCachedItem更新
把当前第一个item关掉。
这个item添加到unusedlist中。
cachedlist第一个删掉。

2.往下拉时,最下面的item出了显示框可以关掉。(firstCachedItem + cachedContentItems.Count) > lastVisibleItem.
具体逻辑跟上面一样。

第四步,把要显示的显示出来。
同样也分两种情况,再多一种是当还没有item的时候
这里需要注意。CustomizeListObject
可以看到。这里主要负责把数据放到每一个item里。并且摆放位置。
这里有个很重要的一点!
可以看到位置的计算是通过编号乘以item的高来算。
在滑动的过程中ngui改变的是UIGrid的localPosition,在tk2d里改变的是Content的localPosition,两者都是一样的。
也就是说。每一个item在滑动过程中localposition都是不变的。
想说的是。DynamicList其实在item的摆放上跟一般的Scrollview是一样的。控制的只是把不用的item隐藏,在需要的时候按item原本的数据摆放。


上图是DynamicList,下图是一般的Scrollview。区别就是上图把左右两边红框内不实例化,但实际也就是这么的排序。(可以想象成,dynamiclist其实也是有这么长的Content)
所以每个item的position就是这么摆放,不需要把这些item移动来移动去。

所以每个item其实就相当于item pool中的一个item。在需要的时候把里面数据填充。
(如果是以前2d游戏,需要计算新的item该放哪,这里因为用的是Scrollview,其实每个item位置是一个接一个的,只是移动父节点)

然后就是把上面新的可显示的item显示
因为上面加了一个,所以第一个item编号往前一位,
获取unused列表第一个Transform,等下使用
把这个transform从unused列表删掉
使用的列表cached添加到最前。
使用这个transform。
打开

把下面的可现实的item显示。
显示这边整段是这样的


这样就完成了!!

你可能感兴趣的:(游戏,unity,NGUI,U3D)