private bool mIsLoadOver = false; //是否加载完成 void Awake() { mTran = transform; mPanel = GetComponent <UIPanel>(); if (mPanel == null) { SQDebug.Log("panel is null"); return; } mScrollView = GetComponent <UIScrollView>(); if (mScrollView == null) { SQDebug.Log("scrollview is null"); return; } //创建显示个数的item for (int i = 0; i < ShowCount; i++) { GameObject obj = new GameObject((i + 1).ToString()); obj.transform.parent = mTran; obj.transform.localPosition = Vector3.zero; obj.transform.localScale = Vector3.one; obj.transform.localRotation = Quaternion.Euler(Vector3.zero); ChatScrollItem item = obj.AddComponent <ChatScrollItem>(); item.indexInScroll = i; mItemList.Add(item); } mIsHorizontal = mScrollView.movement == UIScrollView.Movement.Horizontal ? true : false; mPanel.onClipMove = OnClipMove; mInitPanelPos = mTran.localPosition; mInitPanelClip = mPanel.clipOffset; mPanelHeight = mPanel.height; }
/// <summary> /// 更具显示的数量,生成Item /// </summary> public void InitInstantiateItems() { //创建显示个数的item for (int i = 0; i < ShowCount; i++) { GameObject obj = new GameObject((i + 1).ToString()); obj.transform.parent = mTran; obj.transform.localPosition = Vector3.zero; obj.transform.localScale = Vector3.one; obj.transform.localRotation = Quaternion.Euler(Vector3.zero); ChatScrollItem item = obj.AddComponent <ChatScrollItem>(); item.indexInScroll = i; mItemList.Add(item); } }
/// <summary> /// 设置初始化item位置 /// </summary> /// <param name="index">item的下标</param> private void SetInitItemPos(int index) { ChatScrollItem obj = mItemList[index]; ChatScrollItem last = index <= 0 ? null : mItemList[index - 1]; if (last == null) { obj.transform.localPosition = Vector3.zero; } else { Vector3 pos = last.transform.localPosition; //前一个item的位置 pos.y = pos.y - last.contentHeight - SpaceY; //前一个item位置减去占用的高度和间隔就是当前item的初始位置 obj.transform.localPosition = pos; } }
/// <summary> /// 是否最后一个item在panel的显示范围内 /// </summary> /// <returns></returns> private bool IsTheLastItemOnShow(int allcount) { if (allcount == 0) { return(true); } if (mMaxIndex != allcount - 1)//最大index不是最后一个,肯定不在范围内 { return(false); } int index = mItemIndexDic[mMaxIndex]; //最后一个item在list中对应index ChatScrollItem item = mItemList[index]; float y = mTran.localPosition.y + item.contentHeight; //如果当期panel位置加上item高度 if (y > mNextDownPos) //大于最大滑动到底端的位置,说明item在panel显示范围内 { return(true); } return(false); }
/// <summary> /// 从最后添加一个item /// </summary> private void AddOneItemByLast() { bool b = IsTheLastItemOnShow(mAllCount); //最后一个item是否在panel显示范围内 if (!b) //如果不在直接总数加1 { mAllCount += 1; //总数量+1 } else//如果在范围内将新的item添加到最后 { mScrollView.DisableSpring(); //最上边的item移动到最下边 //最新的最底面的item int index = 0; //数据位置对应的gameobject位置 if (mAllCount < ShowCount) //总数<可以展示的最大数量 { if (mAllCount != 0) { index = mMaxIndex + 1; } } else { index = mItemIndexDic[mMinIndex]; } ChatScrollItem item = mItemList[index]; item.gameObject.SetActive(true); if (mAllCount >= ShowCount)//总数>=可以展示的最大数量 { float itemHeight = item.contentHeight; mMaxIndex++; //新的最底端item数据对应的gameobject位置 int topIndex = mItemIndexDic[mMinIndex]; mItemIndexDic[mMaxIndex] = topIndex; //下次滑动到顶端的位置 //SQDebug.Log("mNextUpPos:" + mNextUpPos); mNextUpPos += (itemHeight + SpaceY); //新的最上边的item index mItemIndexDic.Remove(mMinIndex);//删除之前最顶端的记录 mMinIndex++; DispatchEvent(eFuiScrollViewEvent.UpdateItem, mMaxIndex, item.transform.GetChild(0).gameObject); SQDebug.Log("刷新"); } else { //新的最底端item数据对应的gameobject位置 int topIndex = mItemIndexDic[mMaxIndex]; if (mAllCount != 0) { mMaxIndex++; mItemIndexDic[mMaxIndex] = topIndex + 1; } DispatchEvent(eFuiScrollViewEvent.InitItem, mMaxIndex, item.gameObject); SQDebug.Log("创建"); } //重新设置最底下item的位置和大小 item.contentHeight = NGUIMath.CalculateRelativeWidgetBounds(item.transform).size.y; if (mAllCount != 0)//总数为0 { //重新设置最底下item的位置和大小 ChatScrollItem lastMax = mItemList[mItemIndexDic[mMaxIndex - 1]];//之前最大的item Vector3 vec = lastMax.transform.localPosition; vec.y -= (lastMax.contentHeight + SpaceY); item.transform.localPosition = vec; //最终位置 //下次滑动到底端的位置 float last = mNextDownPos; mNextDownPos += (item.contentHeight + SpaceY); if (vec.y - mInitPanelPos.y < -mPanelHeight)//如果底端位置超过了panel的高度才重新计算裁剪 { //重新设置panel的位置和裁剪 vec = mTran.localPosition; float delta = mNextDownPos - vec.y; vec.y = mNextDownPos; mTran.localPosition = vec; //位置 //裁剪 Vector2 clip = mPanel.clipOffset; clip.y -= delta; mPanel.clipOffset = clip; } } else { float last = mNextDownPos; mNextDownPos += (item.contentHeight + SpaceY); } //总数+1 mAllCount += 1; //SQDebug.Log("mMinIndex:" + mMinIndex + " mMaxIndex: " + mMaxIndex + " contentHeight:" + item.contentHeight + "mNextUpPos:" + mNextUpPos + item.contentHeight + "mNextDownPos:" + mNextDownPos + " last:" + (mNextUpPos - last + 50)); } }
private void MoveOver(eMoveType movetype) { int index = 0; Transform trans; ChatScrollItem item = null; float itemHeight = 0; //item高度 if (movetype == eMoveType.LeftAndUp) //向左或向上滑动 { if (mTran.localPosition.y <= mNextDownPos) { return; } if (mItemIndexDic.TryGetValue(mMaxIndex, out index)) { trans = mItemList[index].transform; } else { SQDebug.LogError("maxIndex is null"); return; } //最上边的item移动到最下边 //最新的最底面的item index = mItemIndexDic[mMinIndex];//数据位置对应的gameobject位置 item = mItemList[index]; itemHeight = item.contentHeight; mMaxIndex++; //新的最底端item数据对应的gameobject位置 int topIndex = mItemIndexDic[mMinIndex]; mItemIndexDic[mMaxIndex] = topIndex; //下次滑动到顶端的位置 //SQDebug.Log("mNextUpPos:" + mNextUpPos); mNextUpPos += (itemHeight + SpaceY); //新的最上边的item index mItemIndexDic.Remove(mMinIndex);//删除之前最顶端的记录 mMinIndex++; item.gameObject.SetActive(true); DispatchEvent(eFuiScrollViewEvent.UpdateItem, mMaxIndex, item.transform.GetChild(0).gameObject); //重新设置最底下item的位置和大小 item.contentHeight = NGUIMath.CalculateRelativeWidgetBounds(item.transform).size.y; ChatScrollItem lastMax = mItemList[mItemIndexDic[mMaxIndex - 1]];//之前最大的item Vector3 vec = lastMax.transform.localPosition; vec.y -= (lastMax.contentHeight + SpaceY); item.transform.localPosition = vec;//最终位置 //下次滑动到底端的位置 float last = mNextDownPos; mNextDownPos += (item.contentHeight + SpaceY); //SQDebug.Log("mMinIndex:" + mMinIndex + " mMaxIndex: " + mMaxIndex + " contentHeight:" + item.contentHeight + "mNextUpPos:" + mNextUpPos + "mNextDownPos:" + mNextDownPos + item.contentHeight + " last:" + (mNextDownPos - last - 50)); } else//向右或向下滑动 { if (mTran.localPosition.y >= mNextUpPos) { return; } //最下边的item移动到最上边 //最新的最顶端的item index = mItemIndexDic[mMaxIndex];//数据位置对应的gameobject位置 item = mItemList[index]; itemHeight = item.contentHeight; mMinIndex--; //新的最顶端item数据对应的gameobject位置 int topIndex = mItemIndexDic[mMaxIndex]; mItemIndexDic[mMinIndex] = topIndex; //下次滑动到顶端的位置 mNextDownPos -= (itemHeight + SpaceY); //新的最底端的item index mItemIndexDic.Remove(mMaxIndex);//删除之前最底端的记录 mMaxIndex--; item.gameObject.SetActive(true); DispatchEvent(eFuiScrollViewEvent.UpdateItem, mMinIndex, item.transform.GetChild(0).gameObject); //重新设置最底下item的位置和大小 item.contentHeight = NGUIMath.CalculateRelativeWidgetBounds(item.transform).size.y; ChatScrollItem lastMin = mItemList[mItemIndexDic[mMinIndex + 1]];//之前最小的item Vector3 vec = lastMin.transform.localPosition; vec.y += (item.contentHeight + SpaceY); item.transform.localPosition = vec;//最终位置 //下次滑动到顶端的位置 float last = mNextUpPos; mNextUpPos -= (item.contentHeight + SpaceY); //SQDebug.Log("mMinIndex:" + mMinIndex + " mMaxIndex: " + mMaxIndex + " contentHeight:" + item.contentHeight + "mNextUpPos:" + mNextUpPos + item.contentHeight + "mNextDownPos:" + mNextDownPos + " last:"+(mNextUpPos - last + 50)); } }