通常我们遇到问题,都是在对滑动列表的各种操作中发现了不可预知的问题(废话)
下面我总结一下我遇到的一些问题:
1. WrapContent 初始化过程中没有调用 onInitializeItem 方法,为什么?
我们可以打开UIWrapContent代码,一探究竟,从此方法来看,我们有可能在UIWrapContent初始化之前,没有
对 onInitializeItem进行实例化,导致没有进入到我们自身的回调方法。
protected virtual void UpdateItem (Transform item, int index)
{
if (onInitializeItem != null)
{
int realIndex = (mScroll.movement == UIScrollView.Movement.Vertical) ?
Mathf.RoundToInt(item.localPosition.y / itemSize) :
Mathf.RoundToInt(item.localPosition.x / itemSize);
onInitializeItem(item.gameObject, index, realIndex);
}
}
2. 当我们只有一个Gird的时候WrapContent的UpdateItem调用了两次,为什么?
我们发现调用UpdateItem地方有很多,但是总结归纳起来,有两个地方在调用
protected virtual void Start ()
{
SortBasedOnScrollMovement();
WrapContent();
if (mScroll != null) mScroll.GetComponent().onClipMove = OnMove;
mFirstTime = false;
}
没错,就是SortBasedOnScrollMovement方法与WrapContent方法在调用
3. 本人遇到的一个坑,当我只有一个Gird的时候,第一次没有初始化,第二次打开界面位置偏移了。
没有初始化的原因:我的Gird的默认是隐藏的,当我向服务器请求消息后,发现有数据才显示出来。但是此时WrapContent的一个坑就是,它enabled=true的时候,只会走一遍Start方法。并且如果你的Gird为隐藏状态,它是不会认为你有容器里有东西的。
public virtual void SortBasedOnScrollMovement ()
{
if (!CacheScrollView()) return;
// Cache all children and place them in order
mChildren.Clear();
for (int i = 0; i < mTrans.childCount; ++i)
{
Transform t = mTrans.GetChild(i);
if (hideInactive && !t.gameObject.activeInHierarchy) continue;
mChildren.Add(t);
}
// Sort the list of children so that they are in order
if (mHorizontal) mChildren.Sort(UIGrid.SortHorizontal);
else mChildren.Sort(UIGrid.SortVertical);
ResetChildPositions();
}
首先,只走一遍是一个大坑。因为我第一次,容器里确实已经隐藏了,t.gameObject.activeInHierarchy 为false,导致mChildren 里一个对象都没有...然后在后续的ResetChildPositions的方法中,没有执行UpdateItem
protected virtual void ResetChildPositions ()
{
for (int i = 0, imax = mChildren.Count; i < imax; ++i)
{
Transform t = mChildren[i];
t.localPosition = mHorizontal ? new Vector3(i * itemSize, 0f, 0f) : new Vector3(0f, -i * itemSize, 0f);
UpdateItem(t, i);
}
}
其次,是偏移,我查了好几遍,发现走了两边。第一遍是对的,第二遍偏移了-100
else if (distance > extents)
{
Vector3 pos = t.localPosition;
pos.x -= ext2;
distance = pos.x - center.x;
int realIndex = Mathf.RoundToInt(pos.x / itemSize);
if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex))
{
t.localPosition = pos;
UpdateItem(t, i);
}
else allWithinRange = false;
}
原因是我在代码里设置了minIndex和maxIndex导致的,默认我设置为0和0了,希望大家注意!!!
目前本人的解决办法是:既然它没有调用刷新,我自己手动调用了一次。方法也很简单,就是找到对应的Object,然后把index穿进去,初始化。如果大家有更好的方法,欢迎留言,互相学习!