[Unity UGUI] 实现可复用Item的ScrollView

您所在的位置:网站首页 scrollview滑动监听 [Unity UGUI] 实现可复用Item的ScrollView

[Unity UGUI] 实现可复用Item的ScrollView

2023-03-29 10:47| 来源: 网络整理| 查看: 265

er大家好我是锡乔君,目前是Unity开发工程师,做过Java,熟悉Android,略懂C++。相对于知乎上的大神,我只是个菜鸟!下面是我的博客地址,有问题欢迎私信讨论,看到会及时回复。

本文主要介绍一种实现可复用Item ScrollView的方法,系统自带的滚动View有一些缺点,其中不能复用Item会造成内存上的开销。当有上万条数据时,这种开销就很大,所以我们实现一个简单版可复用滚动View。效果如下:https://www.zhihu.com/video/1396252077492961280

代码还是没什么难度,主要在于计算ID。

采用MVC模式设计,即Model - View - Controller,首先准备制作预制体和图片资源。View只关心显示,Controller负责将Model填充到View里面。

一、计算Item的位置

首先,我们要确定Content视图一次能显示几个Item?当我们上滑时,第一个Item是渐渐消失的,底部也在出现一个Item,如图:

如上图所示,假设我们的Item高度为100,每个Item之间的间隔是10,Content的高度是320,那么显然我们当前视图最高同时只能存放三个Item,然后在1上滑时,4也在慢慢出现,所以我们复用的Item个数需要是4个,不然1来不及复用,因为他正在显示。

reuseItemCount = Mathf.ceilToInt(Content.Height/(item.height+offsetY))+1

第二,让我们来思考一下如何将数据和复用的Item对应起来?

我们的数据使用List存放的,假设有10条数据,从下标0开始取第一条数据,对应第一个Item。当第一个Item完全被上滑至不可见时,我们复用他,他应该显示第几条数据呢?

从图上我们可以看出来,此时1应该显示第五条数据。

这是上滑的逻辑,我们还要考虑下滑的逻辑,如果此时我们下滑,1重新出现怎么处理呢?

定义startId和endId,startId从0开始,endId = startId+ItemCount-1(注意这里对应数据下标),当滑动时,我们可以动态修改startId和endId的值,并始终维护当前Item显示第几条数据。

二、监听滑动事件

在ScrollView中有一个默认的监听OnValueChange()方法,我们可以给每一个Item添加该方法的响应,当滑动时,每个Item都会判断如何修改和维护自己的ID,就比如Item 1上滑至不可见,那么此时他将自己的ID改为4显示第五条数据。这里我们使用委托的方式来完成。最后比较重要的就是动态的修改Item的位置,如何修改呢?

假设我们以O点为(0,0)点,那么A,B,C点的坐标都很好计算。

最后上代码:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoopList : MonoBehaviour { public float offsetY; private float itemHeight; private float contentHeight; private List _items; private List _models; private RectTransform _content; void Start() { _items = new List(); _models = new List(); GetModels(); _content = transform.Find("Viewport/Content").GetComponent(); GameObject go = LoadPrefab("Prefab/Item"); int itemCount = GetShowItemCount(offsetY,itemHeight); //生成count+1个预制体 SpawnItems(go,itemCount); SetContentSize(itemCount,offsetY,itemHeight); GetComponent().onValueChanged.AddListener(ChangeValue); } public void ChangeValue(Vector2 data) { foreach (var item in _items) { item.OnValueChange(); } } private void SpawnItems(GameObject go,int itemCount) { GameObject itemPrefab = null; LoopListItem item = null; for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3