一、元素自动排版功能
1、首先要往我们的unity项目中导入两个脚本文件,脚本文件名称分别是UIScrollEventListener和CZScrollRect,这两个脚本文件代码如下所示。
1-1、介绍UIScrollEventListener脚本写法。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class UIScrollEventListener : MonoBehaviour, IBeginDragHandler, IEndDragHandler , IPointerUpHandler, IPointerDownHandler , IDragHandler
{
public delegate void VoidDelegate(PointerEventData pdata);
public VoidDelegate onBeginDrag;
public VoidDelegate onEndDrag;
public VoidDelegate onUp;
public VoidDelegate onDown;
public VoidDelegate onDrag;
bool isDrag = false;
List<Image> registers = new List<Image>();
public static UIScrollEventListener Get(GameObject go)
{
UIScrollEventListener listener = go.GetComponent<UIScrollEventListener>();
if (listener == null) listener = go.AddComponent<UIScrollEventListener>();
return listener;
}
public void OnBeginDrag(PointerEventData eventData)
{
isDrag = true;
if (onBeginDrag != null) onBeginDrag(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
isDrag = false;
if (onEndDrag != null) onEndDrag(eventData);
}
public void OnPointerUp(PointerEventData eventData)
{
if (!isDrag) {
SetRegisterEvent(true);
PraseObject(eventData);
SetRegisterEvent(false);
}
if (onUp != null) onUp(eventData);
}
public void OnPointerDown(PointerEventData eventData)
{
if (onDown != null) onDown(eventData);
}
public void OnDrag(PointerEventData eventData) {
if (onDrag != null) onDrag(eventData);
}
public void RegisterButton(GameObject go)
{
Image img = go.GetComponent<Image>();
if (img != null)
{
img.raycastTarget = false;
registers.Add(img);
}
}
void SetRegisterEvent(bool b) {
if (registers.Count > 0)
{
for (int i = 0; i < registers.Count; ++i)
{
registers[i].raycastTarget = b;
}
}
}
void PraseObject(PointerEventData eventData) {
if (registers.Count > 0)
{
for (int i = 0; i < registers.Count; ++i)
{
if (EventSystem.current != null)
{
List<RaycastResult> result = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, result);
foreach (RaycastResult r in result)
{
//Debug.Log(r.gameObject.name);
foreach (Image img in registers)
{
if (img.gameObject.Equals(r.gameObject))
{
InputField inputfield = img.gameObject.GetComponent<InputField>();
if (inputfield != null) inputfield.ActivateInputField();
}
}
}
}
}
}
}
}
1-2、介绍CZScrollRect脚本写法。
using System;
using UnityEngine;
using UnityEngine.UI;
public class ScrollObj
{
public GameObject obj;
public int dex;
}
public class CZScrollRect
{
public enum TipType
{
UNDO_REFRESH = 0,
PULL_REFRESH = 1,
UNDO_APPEND = 2,
PULL_AAPEND = 3,
NODATA = 4,
NONE = 5
}
const int OPEAT_HEIGHT = 100;//高度差判断操作类型
const int INIT_NUM_LIMIT = 8;//列表实例化个数
public delegate void OperatDelegate();
public delegate void OperatObjDelegate(GameObject obj , int index);
public delegate void OperatTextObjDelegate(GameObject obj, TipType t);
public OperatDelegate onRefresh;//下拉刷新时回调
public OperatDelegate onAppend;//需要加载更多时回调
public OperatObjDelegate onScrollObj;//需刷新时回调
public OperatTextObjDelegate onUpdateTextObj;//需刷新文本状态时回调
public ScrollRect scrollRect;//ScrollRect
private RectTransform scrollRectContent;//RectTransform
public GameObject prefab;//实例化的对象
public GameObject text_up;//下拉刷新文本
public GameObject text_down;//上拉加载更多文本
TipType textup_status;
int opeartLen = 0;//记录总长度
public int layoutwidth = 1242;//填写item的长度
public int limitNum = 8;//列表实例化个数
public float interval = 200;//每个item的高度
public float spacing = 5;//每个tiem的间隔
ScrollObj[] list;//用于管理生成的对象
int opeartType;
int pageindex;//页码
bool bHasMore;//是否能加载更多
int halfWidth;
//
public GameObject batchContent;
public CZScrollRect()
{
opeartType = -1;
hasMore = false;
}
/// <summary>
/// 用于控制scrollrect是否能够滑动
/// (用于等待网络请求等业务)
/// </summary>
public bool vertical
{
get{
return scrollRect.vertical;
}set{
scrollRect.vertical = value;
}
}
/// <summary>
/// 是否存在更多
/// </summary>
public bool hasMore
{
get{
return bHasMore;
}set{
bHasMore = value;
}
}
/// <summary>
/// 获取对象所在的索引
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int GetObjIndex(GameObject obj) {
for(int i = 0; i < list.Length; ++i)
{
if (obj.Equals(list[i].obj))
{
return list[i].dex;
}
}
return -1;
}
/// <summary>
/// 初始化参数
/// </summary>
public void Init() {
list = new ScrollObj[Mathf.Max(limitNum, INIT_NUM_LIMIT)];
scrollRectContent = scrollRect.content;
halfWidth = layoutwidth / 2;
//此处监听drag事件
UIScrollEventListener.Get(scrollRect.gameObject).onDrag = (data) =>
{
float recty = -scrollRectContent.rect.y - scrollRect.GetComponent<RectTransform>().sizeDelta.y;//Log.Debug($"{scrollRectContent.anchoredPosition.y} , {recty} , {-scrollRectContent.rect.y}");
if (scrollRectContent.anchoredPosition.y >= recty + OPEAT_HEIGHT)
{
if (bHasMore)
{
//松开可以加载更多
if (textup_status != TipType.UNDO_APPEND) {
textup_status = TipType.UNDO_APPEND;
if (onUpdateTextObj != null) onUpdateTextObj(text_down, TipType.UNDO_APPEND);
}
}
else
{
//没有更多数据了
if (textup_status != TipType.NODATA)
{
textup_status = TipType.NODATA;
if (onUpdateTextObj != null) onUpdateTextObj(text_down, TipType.NODATA);
}
}
opeartType = 1;
}
else if (scrollRectContent.anchoredPosition.y > recty)
{
if (bHasMore)
{
//上拉可以加载更多
if (textup_status != TipType.PULL_AAPEND)
{
textup_status = TipType.PULL_AAPEND;
if (onUpdateTextObj != null) onUpdateTextObj(text_down, TipType.PULL_AAPEND);
}
}
else
{
//没有更多数据了
if (textup_status != TipType.NODATA)
{
textup_status = TipType.NODATA;
if (onUpdateTextObj != null) onUpdateTextObj(text_down, TipType.NODATA);
}
}
opeartType = -1;
}
else if (scrollRectContent.anchoredPosition.y <= -OPEAT_HEIGHT)
{
//松开可以刷新
if (textup_status != TipType.UNDO_REFRESH)
{
textup_status = TipType.UNDO_REFRESH;
if (onUpdateTextObj != null) onUpdateTextObj(text_up, TipType.UNDO_REFRESH);
}
opeartType = 0;
}
else if (scrollRectContent.anchoredPosition.y < 0)
{
//下拉可以刷新
if (textup_status != TipType.PULL_REFRESH)
{
textup_status = TipType.PULL_REFRESH;
if (onUpdateTextObj != null) onUpdateTextObj(text_up, TipType.PULL_REFRESH);
}
opeartType = -1;
}
else
{
opeartType = -1;
}
UpdateUiInfo();
};
//此处是监听鼠标点击事件
UIScrollEventListener.Get(scrollRect.gameObject).onUp = (data) =>
{
if (opeartType == 0)
{
if (onRefresh != null)
{
scrollRect.vertical = false;
onRefresh();
}
}
else if (opeartType == 1)
{
if (bHasMore && onRefresh != null)
{
scrollRect.vertical = false;
onAppend();
}
}
};
scrollRect.onValueChanged.RemoveAllListeners();
scrollRect.onValueChanged.AddListener(OnScrollChange);
}
void OnScrollChange(Vector2 v) {
//TOP TO BUTTOM 计算页码
int curIndex = Mathf.Min(Mathf.Max(Mathf.FloorToInt(scrollRectContent.anchoredPosition.y / (interval + spacing)) - 1, 0), opeartLen - limitNum);
UpdatePageIndex(curIndex);
}
/// <summary>
/// 刷新页面 (重置长度)
/// </summary>
/// <param name="len"></param>
public void Refresh(int len)
{
//Debug.Log($"Refresh len = {len}");
if (len < 0)return;
int count = 0;
for (int i = 0; i < list.Length; ++i) {
if (list[i] == null) list[i] = new ScrollObj();
if (i < len) {
if (list[i].obj == null)
{
list[i].obj = GetNewObject();
}
list[i].dex = i;
list[i].obj.SetActive(true);
SetPosition(list[i].obj, list[i].dex);
if (onScrollObj != null) onScrollObj(list[i].obj, list[i].dex);
count++;
}
else
{
if(list[i].obj != null) list[i].obj.SetActive(false);
}
}
opeartLen = len;
UpdatePageIndex(0);//重置页码
scrollRectContent.localPosition = Vector3.zero;
scrollRect.verticalScrollbar.value = 1;
UpdateUiInfo();
scrollRect.vertical = true;
}
/// <summary>
/// 追加长度
/// </summary>
/// <param name="len"></param>
public void Append(int len)
{
//Debug.Log($"Append len = {len}");
if (len < 0) return;
if(len == 0)
{
if (onUpdateTextObj != null) {
onUpdateTextObj(text_up, TipType.NONE);
onUpdateTextObj(text_down, TipType.NONE);
}
}
if (opeartLen < list.Length) {
int showlen = Mathf.Min(list.Length - opeartLen , len);//Debug.Log($"showlen = {showlen}");
for (int i = 0; i < showlen; ++i) {
int dex = opeartLen + i;//Debug.Log(dex);
if (list[dex] == null) list[dex] = new ScrollObj();
if (list[dex].obj == null)
{
list[dex].obj = GetNewObject();
}
list[dex].dex = dex;
list[dex].obj.SetActive(true);
SetPosition(list[i].obj, list[i].dex);
if (onScrollObj != null) onScrollObj(list[dex].obj, list[dex].dex);
}
}
opeartLen += len;
UpdateUiInfo();
scrollRect.vertical = true;
}
/// <summary>
/// 实时刷新页面
/// </summary>
/// <param name="pdex"></param>
void UpdatePageIndex(int pdex) {
if (opeartLen <= list.Length || pageindex == pdex) return;//Debug.Log($"pdex = {pdex}");
int x = Mathf.FloorToInt(pdex / limitNum);
int y = pdex % limitNum;
for (int i = 0; i < limitNum; ++i)
{
int d = 0;
if (i < y)
{
d = (x + 1) * limitNum + i;
}
else
{
d = Mathf.Max(x, 0) * limitNum + i;
}
if (list[i].dex != d) {
list[i].dex = d;
if (list[i].obj != null) {
SetPosition(list[i].obj, list[i].dex);
if (onScrollObj != null) onScrollObj(list[i].obj, list[i].dex);
}
}
}
pageindex = pdex;
}
/// <summary>
/// 刷新content的高度
/// </summary>
void UpdateUiInfo() {
//Debug.Log($"opeartLen = {opeartLen} {opeartLen * (interval + spacing)} - {scrollRect.GetComponent<RectTransform>().sizeDelta.y}");
scrollRectContent.sizeDelta = new Vector2(0, Math.Max(opeartLen * (interval + spacing), scrollRect.GetComponent<RectTransform>().sizeDelta.y));
if(text_up != null) text_up.transform.localPosition = new Vector3(text_up.transform.localPosition.x, OPEAT_HEIGHT - 50, 0);
if (text_down != null) text_down.transform.localPosition = new Vector3(text_down.transform.localPosition.x, -scrollRectContent.sizeDelta.y - OPEAT_HEIGHT + 50, 0);
}
void SetPosition(GameObject obj , int dex) {
//obj.transform.localPosition = new Vector3(0, -dex * (interval + spacing) - interval / 2, 0);
float y = -dex * (interval + spacing) - interval;
obj.transform.GetComponent<RectTransform>().offsetMin = new Vector2(0 , y);
obj.transform.GetComponent<RectTransform>().offsetMax = new Vector2(0, y + interval);
}
GameObject GetNewObject() {
return GameObject.Instantiate(prefab, scrollRectContent);
}
public void Dispose()
{
scrollRect.onValueChanged.RemoveAllListeners();
scrollRect = null;
scrollRectContent = null;
prefab = null;
text_up = null;
text_down = null;
list = null;
onAppend = null;
onRefresh = null;
onScrollObj = null;
}
}
二、测试ScrollRect中元素自动排版案例
1、首先要在我们的场景中搭建好测试的游戏物体,我这个场景中游戏物体的锚点是随便设置的,你们可以根据需要进行对应不同的测试。
2、新增一个TestScrollView脚本用于测试ScrollRect中元素自动排版,TestScrollView脚本完整代码如下。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestScrollView : MonoBehaviour
{
CZScrollRect scrollcomponent;
GameObject item;
ScrollRect m_ScrollRect;
List<string> str_list = new List<string>
{
"元素1",
"元素2",
"元素3",
"元素4",
"元素5",
"元素6",
"元素7",
"元素8",
"元素9",
"元素10",
"元素11",
"元素12"
};
private void Awake()
{
item = transform.Find("Viewport/Item").gameObject;
m_ScrollRect = gameObject.GetComponent<ScrollRect>();
scrollcomponent = new CZScrollRect();
scrollcomponent.prefab = item;
scrollcomponent.scrollRect = m_ScrollRect;
scrollcomponent.onScrollObj = OnScrollObj;
scrollcomponent.interval = 30;
scrollcomponent.limitNum = 10000;
scrollcomponent.Init();
}
private void Start()
{
if (str_list.Count == 0)
{
scrollcomponent.Refresh(0);
}
else
{
scrollcomponent.Refresh(str_list.Count);
}
}
void OnScrollObj(GameObject obj, int index)
{
Debug.Log("obj name:" + obj.name + " index:" + index);
obj.transform.Find("Text").GetComponent<Text>().text = str_list[index];
}
}
3、ScrollRect中元素自动排版效果展示。
二、ScrollRect中元素自动定位到Viewport可见范围内
1、在做之前,需要在项目中导入DOTween插件。
2、首先要往我们的unity项目中导入一个脚本文件,脚本文件名称是UIScrollRect,这个脚本文件代码如下所示。
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class UIScrollRect : ScrollRect
{
[SerializeField]
private UnityEvent _BeginDragEvent;
[SerializeField]
private UnityEvent _DragEvent;
[SerializeField]
private UnityEvent _EndDragEvent;
public bool LeftOrUpMove { get; private set; }
private Vector3 _BeginDragPosition;
private bool _IsDragEnd = false;
private bool _UseMoveCenter = false;
public bool UseMoveCenter { set { _UseMoveCenter = value; } }
private bool _AutoMoveCenter = false;
private bool AutoMoveCenter { set { _AutoMoveCenter = value; } }
private bool _SkipAnimation = false;
private bool _SkipDragDirection = false;
private Vector3 _ContentPosition = Vector3.zero;
private TweenerCore<Vector3, Vector3, VectorOptions> _DOTweenTo;
public UnityEvent BeginDragEvent
{
set { this._BeginDragEvent = value; }
get { return this.BeginDragEvent; }
}
public UnityEvent DragEvent
{
set { this._DragEvent = value; }
get { return this.DragEvent; }
}
public UnityEvent EndDragEvent
{
set { this.EndDragEvent = value; }
get { return this._EndDragEvent; }
}
public override void OnBeginDrag(PointerEventData point)
{
base.OnBeginDrag(point);
if (this._DOTweenTo != null)
this._DOTweenTo.Pause();
this._BeginDragPosition = this.content.localPosition;
this._BeginDragEvent?.Invoke();
}
public override void OnDrag(PointerEventData point)
{
base.OnDrag(point);
if (this._DOTweenTo != null)
{
this._DOTweenTo.Pause();
this._DOTweenTo = null;
}
this._DragEvent?.Invoke();
}
public override void OnEndDrag(PointerEventData point)
{
base.OnEndDrag(point);
this._IsDragEnd = true;
this._ContentPosition = this.content.localPosition;
this.LeftOrUpMove = this.horizontal ? this._BeginDragPosition.x > this._ContentPosition.x : this._BeginDragPosition.y < this._ContentPosition.y;
this._EndDragEvent?.Invoke();
}
protected override void LateUpdate()
{
base.LateUpdate();
if (this._UseMoveCenter && this._IsDragEnd)
{
Vector3 pos = this.content.localPosition;
Vector3 offetset = pos - this._ContentPosition;
if (Mathf.Abs(this.horizontal ? offetset.x : offetset.y) < 0.2f)
{
this._IsDragEnd = false;
if (this._AutoMoveCenter)
this.OnItemMoveCenter(null, this._SkipAnimation, this._SkipDragDirection);
}
this._ContentPosition = pos;
}
}
/// <summary>
/// 设置中心滑动参数
/// </summmary>
/// <param name="auto">滑动结束后自动调用OnItemMoveCenter</param>
/// <param name="skipAnimation">跳过动画直接设置中心位置</param>
/// <parm name"skipDragDirection">忽略滑动方向,查找距离中心位置最近的item滑动</param>
public void UseMoveMoveCenter(bool auto = true, bool skipAnimation = false, bool skipDragDirection = false)
{
this._UseMoveCenter = true;
this._AutoMoveCenter = auto;
this._SkipAnimation = skipAnimation;
this._SkipDragDirection = skipDragDirection;
_ContentPosition = Vector3.zero;
}
/// <summary>
/// 将target滑动到中文位置,为null时选择距离中心点最近的item滑动
/// </summary>
/// <param name="target">目标item</param>
/// <param name="skipAnimation">跳过动画直接设置中心位置</param>
/// <param name="skipDragDirection">忽略滑动方向,查找距离中心位置最近的item滑动</param>
public void OnItemMoveCenter(Transform target = null, bool skipAnimation = false, bool skipDragDirection = false)
{
int minIndex = 0;
float distance = float.MaxValue;
int count = this.content.childCount;
if (count == 0)
return;
RectTransform scrollRectTrans = this.GetComponent<RectTransform>();
Vector3 pos = scrollRectTrans.localPosition;
//目标存在直接计算到中心位置的距离
if (target != null)
{
RectTransform item = target.GetComponent<RectTransform>();
// 使用Transform转换方法InverseTransformPoint,将item的世界坐标转化为Transform的局部坐标
pos = scrollRectTrans.InverseTransformPoint(item.position);
// 需要注意的事是item的锚点不同带来的偏差,这里锚点的标准值为(0.5f, 0.5f)即锚点在中心位置, 若不是标准值就要去除width和heigth的值
Vector2 pivot = item.pivot;
//滑动方向优先计算水平滑动,vertical
distance = this.horizontal ? (0.5f - pivot.x) * item.rect.width - pos.x : (pivot.y - 0.5f) * item.rect.height - pos.y;
}
else
{
// 遍历计算,距离中心点最近的距离以及对应的索引值
for (int i = 0; i < count; i++)
{
RectTransform item = this.content.GetComponent<RectTransform>();
// 使用Transform转换方法InverseTransformPoint,将item的世界坐标转化为Transform的局部坐标
pos = scrollRectTrans.InverseTransformPoint(item.position);
// 需要注意的事是item的锚点不同带来的偏差,这里锚点的标准值为(0.5f, 0.5f)即锚点在中心位置, 若不是标准值就要去除width和heigth的值
Vector2 pivot = item.pivot;
//滑动方向优先计算水平滑动,vertical
float dis = this.horizontal ? (0.5f - pivot.x) * item.rect.width - pos.x : (pivot.y - 0.5f) * item.rect.height - pos.y;
if (Mathf.Abs(distance) > Mathf.Abs(dis))
{
distance = dis;
minIndex = i;
}
}
}
bool dragDirection = !skipDragDirection && target == null;
distance = this.horizontal ? this.CalculateHorizontalDistance(distance, minIndex, count, dragDirection) : this.CalculateVerticalDistance(distance, minIndex, count, dragDirection);
pos = this.content.localPosition;
if (this.horizontal)
pos.x = distance;
else
pos.y = distance;
// 跳过动画,直接设置坐标
if (skipAnimation)
{
this.content.localPosition = pos;
return;
}
//使用dotween动画移动, elasticity滑到头回弹的时间
_DOTweenTo = (TweenerCore<Vector3, Vector3, VectorOptions>)this.content.DOLocalMove(pos, this.elasticity).OnComplete(() =>
{
this._DOTweenTo = null;
});
}
/// <summary>
/// 计算水平方向到中心点位置距离
/// </summary>
private float CalculateHorizontalDistance(float distance, int minIndex, int count, bool dragDirection)
{
RectTransform rect = this.GetComponent<RectTransform>();
//防止回弹计算
//当item为null时,查找距离中心点最近的item,并滑动到中心点,当鼠标拖拽滑动结束时,自动移动到中心点的方向可能与鼠标拖拽方向相反,因此需要计算,不要计算时将_SkipDragDirection 设置为true
if (dragDirection)
{
int index = minIndex;
float dis = distance;
//使用while,是因为可能存在多列,相同列上的距离是一样的,需要多次查找拖拽方向上的item
while (index < count && index >= 0 && dis == distance)
{
if (this.LeftOrUpMove)
{
if (distance > 0)
index++;
}
else if (distance < 0)
index--;
if (index == minIndex)
break;
RectTransform item = this.content.GetChild(index).GetComponent<RectTransform>();
Vector2 pivot = item.pivot;
Vector3 pos = rect.InverseTransformPoint(item.position);
distance = (pivot.x - 0.5f) * item.rect.width - pos.x;
}
distance += this.content.localPosition.x;
if (this.movementType != ScrollRect.MovementType.Unrestricted)
{
if (distance >= 0)
distance = 0;
else
{
float dragMaxDistance = rect.rect.width - this.content.rect.width;
if (distance < dragMaxDistance)
distance = dragMaxDistance;
}
}
}
return distance;
}
/// <summary>
/// 计算水平方向到中心点位置距离
/// </summary>
private float CalculateVerticalDistance(float distance, int minIndex, int count, bool dragDirection)
{
RectTransform rect = this.GetComponent<RectTransform>();
//防止回弹计算
//当item为null时,查找距离中心点最近的item,并滑动到中心点,当鼠标拖拽滑动结束时,自动移动到中心点的方向可能与鼠标拖拽方向相反,因此需要计算,不要计算时将_SkipDragDirection 设置为true
if (dragDirection)
{
float dis = distance;
int index = minIndex;
//使用while,是因为可能存在多行,相同列上的距离是一样的,需要多次查找拖拽方向上的item
while (index < count && index >= 0 && dis == distance)
{
if (this.LeftOrUpMove)
{
if (distance < 0)
index++;
}
else if (distance > 0)
index--;
if (index == minIndex)
break;
RectTransform item = this.content.GetChild(index).GetComponent<RectTransform>();
Vector2 pivot = item.pivot;
Vector3 pos = rect.InverseTransformPoint(item.position);
distance = (pivot.y - 0.5f) * item.rect.height - pos.y;
}
}
distance += this.content.localPosition.y;
//Unrestricted滑动到头没有回弹,有回弹的无法将最后或者最前的item移动到中心点位置
if (this.movementType != ScrollRect.MovementType.Unrestricted)
{
if (distance <= 0)
distance = 0;
else
{
float dragMaxDistance = this.content.rect.height - rect.rect.height;
if (distance > dragMaxDistance)
distance = dragMaxDistance;
}
}
return distance;
}
}
3、修改游戏场景中名为Scroll View游戏物体身上的ScrollRect组件,修改方式就是把ScrollRect组件替换成上述的UIScrollRect。
3-1、没修改前Scroll View游戏物体身上的ScrollRect组件效果如下所示。
3-2、修改后Scroll View游戏物体身上的ScrollRect组件效果如下所示。
4、修改TestScrollView脚本测试ScrollRect中元素自动定位到Viewport可见范围内是否可行,TestScrollView脚本完整代码如下。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestScrollView : MonoBehaviour
{
CZScrollRect scrollcomponent;
GameObject item;
ScrollRect m_ScrollRect;
UIScrollRect m_UIScrollRect;
GameObject m_targetGo; //需要定位到的元素物体
List<string> str_list = new List<string>
{
"元素1",
"元素2",
"元素3",
"元素4",
"元素5",
"元素6",
"元素7",
"元素8",
"元素9",
"元素10",
"元素11",
"元素12",
"元素13",
"元素14",
"元素15",
"元素16",
"元素17",
"元素18",
"元素19",
"元素20"
};
private void Awake()
{
item = transform.Find("Viewport/Item").gameObject;
m_ScrollRect = gameObject.GetComponent<ScrollRect>();
m_UIScrollRect = gameObject.GetComponent<UIScrollRect>();
scrollcomponent = new CZScrollRect();
scrollcomponent.prefab = item;
scrollcomponent.scrollRect = m_ScrollRect;
scrollcomponent.onScrollObj = OnScrollObj;
scrollcomponent.interval = 30;
scrollcomponent.limitNum = 10000;
scrollcomponent.Init();
}
private void Start()
{
if (str_list.Count == 0)
{
scrollcomponent.Refresh(0);
}
else
{
scrollcomponent.Refresh(str_list.Count);
}
Debug.Log("m_targetGo:" + m_targetGo);
m_UIScrollRect.OnItemMoveCenter(m_targetGo.GetComponent<RectTransform>());
}
void OnScrollObj(GameObject obj, int index)
{
//假设我们想要让元素10在Viewport可见范围内居中显示
if (index == 9)
{
m_targetGo = obj;
obj.transform.Find("Text").GetComponent<Text>().text = "定位元素" + str_list[index];
}
else
{
obj.transform.Find("Text").GetComponent<Text>().text = str_list[index];
}
Debug.Log("obj name:" + obj.name + " index:" + index);
}
}