UGUI Scrollrect滚动优化:无限循环利用
2016-06-23 04:00
639 查看
1 功能描述
在做排行榜类似界面时,item非常多,可能有几百个,一次创建这么多GameObject是非常卡的。为此,使用只创建可视区一共显示的个数,加上后置准备个数。如图所示图中红色框是可视区,可视区一共可显示4个item,后置准备1个item.当向左滑,0号滑出可视区,4号进入可视区,把0号GameObject位置放在滑动面板最后,如同所示
同时更新滑动面板大小,和每个条目信息。这样循环下去一共创建5个gameobjec,重复利用,实现显示N个条目。如图所示
只创建了5个GameObject,可以实现N个条目的显示。
2 详细设计
2.1 初始化滑动面板
void InitValue() { if (ConstraintCount <= 0) ConstraintCount = 1; Debug.Log("maxIndex = "+ maxIndex); if (minIndex > maxIndex) minIndex = maxIndex; mTrans = transform; mRTrans = transform.GetComponent<RectTransform>(); mScroll = transform.parent.GetComponent<ScrollRect>(); mHorizontal = mScroll.horizontal; SR_size =transform.parent.GetComponent<RectTransform>().rect.size; //四角坐标 横着数 conners[0] = new Vector3(-SR_size.x / 2f, SR_size.y / 2f,0); conners[1] = new Vector3(SR_size.x / 2f, SR_size.y / 2f,0); conners[2] = new Vector3(-SR_size.x / 2f, -SR_size.y / 2f,0); conners[3] = new Vector3(SR_size.x / 2f, -SR_size.y / 2f,0); for (int i = 0; i < 4; i++) { Vector3 temp = transform.parent.TransformPoint(conners[i]);//转化为世界坐标,4个顶点 conners[i].x = temp.x; conners[i].y = temp.y; } mRTrans.pivot = new Vector2(0, 1);//设置panel的中心在左上角 mScroll.onValueChanged.AddListener(delegate { WrapContent(); });//添加滚动事件回调 startPos = mTrans.localPosition; }
1.得到显示区域的4个顶点的世界坐标
2.当产生滚动时,添加滚动委托
2.2 重置滑动面板大小
void UpdateRectsize(Vector2 pos,bool isLast = true) { if (arrangeType == ArrangeType.Vertical) { mRTrans.sizeDelta = new Vector2(pos.x + cell_x/2, ConstraintCount * cell_y); } else { mRTrans.sizeDelta = new Vector2(ConstraintCount * cell_x, -pos.y + cell_y/2); } }
当有新的条目加入时要重新设置滑动层的大小,相当于添加ContentSizeFitter组件。
2.3滑动更新
float min = conner_local[0].x - cell_x;//显示区域 float max = conner_local[3].x + cell_x; for (int i = 0, imax = mChild.Count; i < imax; i++) { Transform temp = mChild[i]; float distance = temp.localPosition.x - center.x; if (distance <-extents) { Vector2 pos = temp.localPosition; pos.x += extents * 2f; int realIndex = getRealIndex(pos); if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex)) { if (i == imax -1) UpdateRectsize(pos,true); else UpdateRectsize(pos); temp.localPosition = pos; //设置Item内容 UpdateItem(temp, i, realIndex); } } if (distance > extents) { Vector2 pos = temp.localPosition; pos.x -= extents * 2f; int realIndex = getRealIndex(pos); if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex)) { temp.localPosition = pos; //设置Item内容 UpdateItem(temp, i, realIndex); } }
1.在滑动委托中,每次遍历所有的创建的GameObject(这里是5个)
2.当水平向左滑动时,当GameObject超过可视区的最左边,把它放在可视区的最右边的预备显示位置,如图所示,0号GameObject从最前变为最后。同时增加滑动面板大小,和0号GameObject的信息显示(把0置为5)
3.当水平向右滑动时,当当GameObject超过可视区的最右边,把它放在可视区的最左边的预备显示位置,如图所示,0号GameObject从最前后为最前。0号GameObject的信息显示(把10置为5)。这样实现无限滚动。
相关文章推荐
- Android UI设计技巧
- serialVersionUID 作用
- std::unique函数的使用
- Leet Code 51 N-Queens - N皇后问题 - Java
- Leet Code 52 N-Queens II - N皇后问题 - Java
- [一句秒懂] iOS8.0-UIAlertController介绍
- UEditor(百度富文本编辑器)的暴力使用
- String-vs-StringBuilder-vs-StringBuffer
- KVC setvalue:forkey与setvalue:forkeypath的区别
- OpenJudge 1058 Guideposts | BZOJ 3328 PYXFIB
- LeetCode-62-Unique Paths
- 信息无缝滚动效果marquee
- Request.url请求路径的一些属性
- UIKit笔记大全
- iOS学习——UIView圆角图片的设置方法
- APUE(4)---文件和目录 (1)
- 测试基础之易用性测试
- Druid数据库连接池
- Errors occurred during the build.
- Arduino控制直流电机