先上Unity里面的组件的详情




接着是代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MyScrollViewControllerB : MonoBehaviour
{
#region Demo贪方便,从编辑上拖上来的物体//
//滚动的ScrollView//
public ScrollRect _scrollRect;
//Mask蒙板,目标是显示区域内的Item,避免在更换Item位置的时候造成直接的视觉误差//
public RectTransform _viewRect;
//ScrollView里的Content//
public RectTransform _content;
//预设的物体//
public Item _item;
#endregion
//预期想要出现的行数//
public int _itemAllRowCount = 100;
//蒙板作用下,上下缓冲的行数//
public int _hideRowCount = 2;
//预期要出现的列数//
public int _columnMax = 3;
//蒙板作用下,显示的最大行数//
int _showRowCount;
//物体的padding//
public RectOffset _itemPadding;
//Content的padding//
public RectOffset _contentPadding;
//字典,记录每一行对应的Item或者ItemList//
Dictionary<int , List<Item>> _dictToShowingItem = new Dictionary<int, List<Item>> ();
//保存从字典中移除的Item//
List<Item> tempItemList = new List<Item> ();
//Item的宽和高//
Vector2 _itemSize;
// Use this for initialization
void Start ()
{
//初始化获取Item的宽和高//
_itemSize = _item.GetComponent<RectTransform> ().sizeDelta;
_itemSize.x += (_itemPadding.left + _itemPadding.right);
_itemSize.y += (_itemPadding.top + _itemPadding.bottom);
//根据Item的高度和蒙板的高度,确定可视范围内的最大Item行数//
_showRowCount = Mathf.CeilToInt (_viewRect.sizeDelta.y / _itemSize.y);
//根据预期出现的行数设置Conten的大小//
_content.sizeDelta = new Vector2 (_content.sizeDelta.x, _itemSize.y * _itemAllRowCount);
//添加滚动监听事件//
_scrollRect.onValueChanged.AddListener (OnScrollRectValueChange);
//
int initRowCount = _itemAllRowCount > (_showRowCount + _hideRowCount * 2) ? (_showRowCount + _hideRowCount * 2) : _itemAllRowCount;
for (int rowIndex = 1; rowIndex <= (initRowCount); rowIndex++) {
List<Item> tempList = new List<Item> ();
for (int columnIndex = 0; columnIndex < _columnMax; columnIndex++) {
Item tempItem = Instantiate (_item, _content) as Item;
tempItem._text.text = ((rowIndex - 1) * _columnMax + columnIndex).ToString ();
tempItem.GetComponent<RectTransform> ().anchoredPosition = new Vector2 ((columnIndex - ((_columnMax - 1) / 2f)) * _itemSize.x, -rowIndex * _itemSize.y);
tempList.Add (tempItem);
}
_dictToShowingItem.Add (rowIndex, tempList);
}
foreach (int key in _dictToShowingItem.Keys) {
Debug.Log ("------------------ key = " + key);
}
lastIndex = 0;
}
void OnScrollRectValueChange (Vector2 vect)
{
if (_content.anchoredPosition.y < 0 || _content.anchoredPosition.y > _content.sizeDelta.y - _viewRect.sizeDelta.y) {
Debug.Log ("超出范围了,不变化!");
return;
}
int index = Mathf.CeilToInt (_content.anchoredPosition.y / _itemSize.y);
this.OnItemListChange (index);
}
//上一次滚动的Index//
int lastIndex;
//传入当前Content位置所代表的Index,去看Content的RectTransform吧//
void OnItemListChange (int index)
{
if (lastIndex == index)
return;
Debug.Log ("index = " + index);
int minIndex = (index - _hideRowCount);
//必须要减 1 ,是因为index自身占用了一行//
int maxIndex = (index + _hideRowCount + _showRowCount - 1);
if (lastIndex < index) {
Debug.Log ("往上移动!");
//因为是往上移动,所以先移除上方不需要的Item,移除的个数的话,视情况吧,一般来说两倍的缓冲行数应该可以了//
for (int key = minIndex - (_hideRowCount * 2 + _showRowCount); key < minIndex; key++) {
if (_dictToShowingItem.ContainsKey (key)) {
List<Item> tempItems = null;
_dictToShowingItem.TryGetValue (key, out tempItems);
_dictToShowingItem.Remove (key);
for (int i = 0; i < tempItems.Count; i++) {
tempItemList.Add (tempItems [i]);
}
Debug.Log ("tempItemList.cout = " + tempItemList.Count);
} else {
Debug.Log ("key = " + key + " 不存在!");
}
}
//移除完毕后,添加下方需要增加的Item//
for (int rowIndex = minIndex; rowIndex < maxIndex; rowIndex++) {
if (rowIndex <= 0 || rowIndex > _itemAllRowCount)
return;
if (!_dictToShowingItem.ContainsKey (rowIndex)) {
Debug.Log ("改变ITem的位置");
List<Item> tempItems = new List<Item> ();
for (int columnIndex = 0; columnIndex < _columnMax; columnIndex++) {
if (tempItemList.Count == 0) {
Debug.Log ("实例化的Item不够用了!!");
tempItemList.Add (Instantiate (_item, _content) as Item);
}
Item tempItem = tempItemList [0];
tempItem._text.text = ((rowIndex - 1) * _columnMax + columnIndex).ToString ();
tempItem.GetComponent<RectTransform> ().anchoredPosition = new Vector2 ((columnIndex - ((_columnMax - 1) / 2f)) * _itemSize.x, -rowIndex * _itemSize.y);
tempItems.Add (tempItem);
tempItemList.RemoveAt (0);
}
_dictToShowingItem.Add (rowIndex, tempItems);
}
}
} else {
//和往上移动类似的//
Debug.Log ("往下移动!");
//区别在这里,for循环//
for (int key = maxIndex + (_hideRowCount * 2); key > maxIndex; key--) {
if (_dictToShowingItem.ContainsKey (key)) {
List<Item> tempItems = null;
_dictToShowingItem.TryGetValue (key, out tempItems);
_dictToShowingItem.Remove (key);
for (int i = 0; i < tempItems.Count; i++) {
tempItemList.Add (tempItems [i]);
}
Debug.Log ("tempItemList.cout = " + tempItemList.Count);
} else {
Debug.Log ("key = " + key + " 不存在!");
}
}
//区别在这里,for循环//
for (int rowIndex = maxIndex; rowIndex > minIndex; rowIndex--) {
if (rowIndex <= 0 || rowIndex > _itemAllRowCount)
return;
if (!_dictToShowingItem.ContainsKey (rowIndex)) {
Debug.Log ("改变ITem的位置");
List<Item> tempItems = new List<Item> ();
for (int columnIndex = 0; columnIndex < _columnMax; columnIndex++) {
if (tempItemList.Count == 0) {
Debug.Log ("实例化的Item不够用了!!");
tempItemList.Add (Instantiate (_item, _content) as Item);
}
Item tempItem = tempItemList [0];
tempItem._text.text = ((rowIndex - 1) * _columnMax + columnIndex).ToString ();
tempItem.GetComponent<RectTransform> ().anchoredPosition = new Vector2 ((columnIndex - ((_columnMax - 1) / 2f)) * _itemSize.x, -rowIndex * _itemSize.y);
tempItems.Add (tempItem);
tempItemList.RemoveAt (0);
}
_dictToShowingItem.Add (rowIndex, tempItems);
}
}
}
lastIndex = index;
}
}
Item的代码很简单,就是把Item的Text暴露出来就好,用于观察的。
暂时就这样,还没实际应用过,不过在demo里测了,感觉还行。
网友评论