Unity之WrapContent,列表滑动问题总结

通常我们遇到问题,都是在对滑动列表的各种操作中发现了不可预知的问题(废话)

下面我总结一下我遇到的一些问题:

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穿进去,初始化。如果大家有更好的方法,欢迎留言,互相学习!




你可能感兴趣的:(Unity,Bug相关)