UnityUGUIScrollView性能优化,滑动列表的itemcell重复利⽤
unity中利⽤ugui制作scrollview有多个格⼦滑动时,最直接的做法是创建对应数量个格⼦节点,利⽤GameObject.Instanate创建节点本⾝就是性能开销很⼤的,如果有500个,1000个或者更多数据要显⽰,要创建这么多个节点,那么这卡顿⼀定很明显,这个数量级⽤这个做法实为下策。 如果接触过安卓/iOS原⽣app开发的应该记得它们的Scrollview / Tableview是有⼀套Item/Cell的复⽤机制的,就是当某个节点滑动出Scrollview 范围时,消失了不显⽰了,那么则移动到新的等待重新进⼊Scrollview 视野的位置重复利⽤,填充新的数据来显⽰,⽽不是创建新的节点来显⽰新的数据,从⽽节约性能的开销,所以即使显⽰⼗万条数据也不会卡顿。 通过这个思路,⽤Unity的UGUI 实现了⼀遍,以此来提⾼显⽰⼤量数据时的Scrollview性能,这是⼗分有效的。 缺点:但也要注意的问题是,每个节点显⽰的数据总是随着Scrollview的滑动⽽变化的,也就是说节点和并不是某条数据绑定,⽽是动态变化的。所以,操作cell节点的UI引起数据变化时,需要我们谨慎操作,考虑到UI的cell节点所对应的的数据是哪条。
⽤法:
在Canvas节点下创建ScrollGridVertical节点,挂上ScrollGridVerticalTest.cs,然后创建cell,挂到ScrollGridVerticalTest.cs脚本下即
可运⾏。
励志小说推荐
ScrollGridVerticalTest.cs
ScrollGridHorizontalTest.cs using System .Collections ;using System .Collections .Generic ;using UnityEngine ;using UnityEngine .UI ;public class ScrollGridVerticalTest : MonoBehaviour { //将模板cell 的GameObject 的节点拉到这⾥。 public GameObject tempCell ; void Start () { ScrollGridVertical scrollGridVertical = gameObject .AddComponent <ScrollGridVertical >(); //步骤⼀:设置模板cell 。 scrollGridVertical .tempCell = tempCell ; //步骤⼆:设置cell 刷新的事
件监听。 scrollGridVertical .AddCellListener (this .OnCellUpdate ); //步骤三:设置数据总数。 //如果数据有新的变化,重新直接设置即可。 scrollGridVertical .SetCellCount (183); } /// <summary> /// 监听cell 的刷新消息,修改cell 的数据。 /// </summary> /// <param name="cell"></param> private void OnCellUpdate (ScrollGridCell cell ) { cell .gameObject .GetComponentInChildren <Text >().text = cell .index .ToString (); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
杨官寨遗址
20
21
22
23
24
25
26
27
28
29
ScrollGridCell.cs using UnityEngine ;using UnityEngine .UI ;public class ScrollGridHorizontalTest :
MonoBehaviour { public GameObject tempCell ; void Start () { ScrollGridHorizontal scrollGridVertical = gameObject .AddComponent <ScrollGridHorizontal >(); scrollGridVertical .tempCell = tempCell ; scrollGridVertical .AddCellListener (this .OnCellUpdate ); scrollGridVertical .SetCellCount (153); } private void OnCellUpdate (ScrollGridCell cell ) { cell .gameObject .GetComponentInChildren <Text >().text = cell .index .ToString (); }}股票解禁
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
相声剧18
19
20
ScrollGridVertical.cs using System .Collections .Generic ;using UnityEngine ;public class ScrollGridCell : MonoBehaviour { private int _x ; private int _y ; private int _index ; private int _objIndex ; public int x { get { return _x ; } } public int y { get { return _y ; } } /// <summary> /// ScrollView 滑动时,根据所显⽰数据⽽刷新变化的数据索引index ,不断变化。 /// </summary> public int index { get { return _index ; } } /// <summary> /// 每个克隆出来的cell 的GameObject 所标记的唯⼀且固定的objIndex ,确定后不再变化。 /// </summary> public int objIndex { get { return _objIndex ; } } /// <summary> /// 更新cell 所滑动到的新的位置。 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="index"></param> public void UpdatePos (int x , int y , int index ) { this ._x = x ; this ._y = y ; this ._index = index ; } public void SetObjIndex (int objIndex ) { this ._objIndex = objIndex ; }}白矾是什么东西
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39using System .Collections .Generic ;using UnityEngine ;using UnityEngine .UI ;public class ScrollGridVertical : MonoBehaviour { public GameObject tempCell ;//模板cell ,以此为⽬标,克隆出每个cell 。 private int cellCount ;//要显⽰数据的总数。 private float cellWidth ; private float cellHeight ; private List <System .Action <ScrollGridCell >> onCellUpdateList = new List <System .Action <ScrollGridCell >>(); private ScrollRect scrollRect ; private int row ;//克隆cell 的GameObject 数量的⾏。 private int col ;//克隆cell 的GameObject 数量的列。 private List <GameObject > cellList = new List <GameObject >(); private bool inited ;1
2
3
4
5
吃海鲜不能吃什么6
凤凰一号7
符号网名
8
9
10
11
12
13
14
15
16
17
18
19
20
private bool inited ; public void AddCellListener (System .Action <ScrollGridCell > call ) { this .onCellUpdateList .Add (call ); this .RefreshAllCells (); } public void RemoveCellListener (System .Action <ScrollGridCell > call ) { this .onCellUpdateList .Remove (call ); } /// <summary> /// 设置ScrollGrid 要显⽰的数据数量。 /// </summary> /// <param name="count"></param> public void SetCellCount (int count ) { this .cellCount = Mathf .Max (0, count ); if (this .inited == fal ) { this .Init (); } //重新调整content 的⾼度,保证能够包含范围内的cell 的anchoredPosition ,这样才有机会显⽰。 float newContentHeight = this .cellHeight * Mathf .CeilToInt ((float )cellCount / this .col ); float newMinY = -newContentHeight + this .scrollRect .viewport .rect .height ; float maxY = this .scrollRect .content .offtMax .y ; newMinY += maxY ;//保持位置 newMinY = Mathf .Min (maxY , newMinY );//保证不⼩于viewport 的⾼度。 this .scrollRect .content .offtMin = new Vector2(0, newMinY ); this .CreateCells (); } private void Init () { if (tempCell == null ) { Debug .LogError ("tempCell 不能为空!"); return ; } this .inited = true ; this .tempCell .SetActive (fal ); //创建ScrollRect 下的viewpoint 和content 节点。 this .scrollRect = gameObject .AddComponent <ScrollRect >(); this .scrollRect .vertical = true ; t
his .scrollRect .horizontal = fal ; GameObject viewport = new GameObject ("viewport", typeof (RectTransform )); viewport .transform .parent = transform ; this .scrollRect .viewport = viewport .GetComponent <RectTransform >(); GameObject content = new GameObject ("content", typeof (RectTransform )); content .transform .parent = viewport .transform ; this .scrollRect .content = content .GetComponent <RectTransform >(); //设置视野viewport 的宽⾼和根节点⼀致。 this .scrollRect .viewport .localScale = ; this .scrollRect .viewport .SetIntAndSizeFromParentEdge (RectTransform .Edge .Top , 0, 0); this .scrollRect .viewport .SetIntAndSizeFromParentEdge (RectTransform .Edge .Left , 0, 0); this .scrollRect .viewport .SetIntAndSizeFromParentEdge (RectTransform .Edge .Right , 0, 0); this .scrollRect .viewport .SetIntAndSizeFromParentEdge (RectTransform .Edge .Bottom , 0, 0); this .scrollRect .viewport .anchorMin = ; this .scrollRect .viewport .anchorMax = ; //设置viewpoint 的mask 。 this .scrollRect .viewport .gameObject .AddComponent <Mask >().showMaskGraphic = fal ; Image image = this .scrollRect .viewport .gameObject .AddComponent <Image >(); Rect viewRect = this .scrollRect .viewport .rect ;202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485