用两种简单的方式实现unity的分页效果
2020-04-15 14:57
190 查看
因为客户使用软件产生的数据越来越多,每有一个数据就要多创建一个预制体,所以内存消耗很大,因此需要开发分页功能。 先百度找了一圈,发现了不少案列,总结了一些自己的经验,并做了两个小Demo分享给大家。 思路:所谓的分页效果,其实就是点击下一页或者上一页重新加载一次数据(覆盖掉之前的数据)。 有两种方法: 第一种是重新加载数据,并且绑定相关的事件等。这种方法可能会触发一个BUG,一个控件可以绑定多个事件,切换下一页的时候记得清除已经绑定的一些事件。 第二种是将所有的数据人一个父类游戏物体,然后直接摧毁父类物体下的所有数据重新创建。这种方法简单暴力,但是可能会造成一些资源的浪费。 第一种方法参考[UGui实现分页](https://blog.csdn.net/andyhebear/article/details/50480453)个人对代码做了一些优化与修正了原来有的一些错误,这里不再多提,思路可以看原博主的讲解,重点来讲一下第二种方法。 首先,想实现分页效果,我们需要知道会用到什么数据。 代码层: 1、数据的总数量 2、每一页显示的数量 3、一共多少页=数据的总数量/每一页的数量 4、当前的页码 控件层: 1、多个子物体预制件,一页需要显示几个则加载几个 2、父物体,用来存放所有的子物体 既然已经知道了需要用到的数据,接下来说一下如何实现。 第一步、对所有的数据初始化,绑定控件,拿到数据等。
/// <summary> /// 初始化UGUI /// </summary> private void InitUGUI() { BtnNext = GameObject.Find("Canvas/BtnNext").GetComponent<Button>(); BtnPrevious = GameObject.Find("Canvas/BtnPrevious").GetComponent<Button>(); PanelText = GameObject.Find("Canvas/PanelText").GetComponent<Text>(); gameObjectPrefab = (GameObject)Resources.Load("Prefabs/Data"); //为上一页按钮与下一页按钮添加事件 BtnNext.onClick.AddListener(()=>{Next(); }); BtnPrevious.onClick.AddListener(() => { Previous(); }); } /// <summary> /// 初始化元素 /// </summary> private void Init() { //计算元素总个数 items = new List<int>(); for (int i = 0; i < 16; i++) { var index = Random.Range(1, 4); items.Add(index); } ItemsCount = items.Count; //计算总页数 PageCount = items.Count % 4 == 0 ? items.Count / 4 : items.Count / 4 + 1; if (items.Count <= 4) PageCount = 1; //调用绑定页数方法 //UpdateUI(PageIndex); FirstLoadUI(PageIndex); //更新界面页数 PanelText.text = string.Format("{0}/{1}", PageIndex.ToString(), PageCount.ToString()); }
第二步,写一个加载数据的方法,初次加载、点击上一页或者下一页按钮分别会执行一次、并且根据页码加载相对应的数据。
/// <summary> /// 绑定页数方法 /// </summary> /// <param name="当前页码"></param> private void UpdateUI(int currentIndex) { //没有数据则直接return if (ItemsCount <= 0) { return; } for (int i = (PageIndex-1) * 4; i < ((PageIndex-1) * 4 + 4 > ItemsCount ? ItemsCount : (PageIndex-1) * 4 + 4); i++) { var needGameObject = Instantiate(gameObjectPrefab) as GameObject; needGameObject.transform.SetParent(ParentObj.transform); needGameObject.GetComponent<Image>().sprite = LoadSprite(items[i].ToString()); } }
第三步:添加控件的相关代码
/// <summary> /// 下一页事件 /// </summary> private void Next() { //最后一页禁止翻页 if (PageIndex == PageCount) return; if (PageIndex >= PageCount) PageIndex = PageCount; DestroyChildObject(ParentObj); PageIndex += 1; UpdateUI(PageIndex); //更新页面页数 PanelText.text = string.Format("{0}/{1}", PageIndex.ToString(), PageCount.ToString()); } private void Previous() { //第一页禁止翻页 if (PageIndex ==1) return; DestroyChildObject(ParentObj); PageIndex -= 1; UpdateUI(PageIndex); //更新页面页数 PanelText.text = string.Format("{0}/{1}", PageIndex.ToString(), PageCount.ToString()); }
下面附上完整的代码与Demo链接
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class FenYeTest2 : MonoBehaviour { private List<int> items; /// <summary> /// 总数据数量 /// </summary> private int ItemsCount; /// <summary> /// 总页数,没有数据默认为1 /// </summary> private int PageCount=1; /// <summary> /// 当前页数的标签 /// </summary> private Text PanelText; /// <summary> /// 当前页面索引 /// </summary> private int PageIndex=1; /// <summary> /// 上一页按钮 /// </summary> private Button BtnPrevious; /// <summary> /// 下一页按钮 /// </summary> private Button BtnNext; /// <summary> /// 父物体组件,所有的子物体全部挂在这个上 /// </summary> public GameObject ParentObj; /// <summary> /// 需要使用的预制件,该游戏物体上会绑定各种事件、资源等,同时也是子物体 /// </summary> public GameObject gameObjectPrefab; void Start() { InitUGUI(); Init(); } /// <summary> /// 初始化UGUI /// </summary> private void InitUGUI() { BtnNext = GameObject.Find("Canvas/BtnNext").GetComponent<Button>(); BtnPrevious = GameObject.Find("Canvas/BtnPrevious").GetComponent<Button>(); PanelText = GameObject.Find("Canvas/PanelText").GetComponent<Text>(); gameObjectPrefab = (GameObject)Resources.Load("Prefabs/Data"); //为上一页按钮与下一页按钮添加事件 BtnNext.onClick.AddListener(()=>{Next(); }); BtnPrevious.onClick.AddListener(() => { Previous(); }); } /// <summary> /// 下一页事件 /// </summary> private void Next() { //最后一页禁止翻页 if (PageIndex == PageCount) return; if (PageIndex >= PageCount) PageIndex = PageCount; DestroyChildObject(ParentObj); PageIndex += 1; UpdateUI(PageIndex); //更新页面页数 PanelText.text = string.Format("{0}/{1}", PageIndex.ToString(), PageCount.ToString()); } private void Previous() { //第一页禁止翻页 if (PageIndex ==1) return; DestroyChildObject(ParentObj); PageIndex -= 1; UpdateUI(PageIndex); //更新页面页数 PanelText.text = string.Format("{0}/{1}", PageIndex.ToString(), PageCount.ToString()); } /// <summary> /// 初始化元素 /// </summary> private void Init() { //计算元素总个数 items = new List<int>(); for (int i = 0; i < 16; i++) { var index = Random.Range(1, 4); items.Add(index); } ItemsCount = items.Count; //计算总页数 PageCount = items.Count % 4 == 0 ? items.Count / 4 : items.Count / 4 + 1; if (items.Count <= 4) PageCount = 1; //调用绑定页数方法 //UpdateUI(PageIndex); UpdateUI(PageIndex); //更新界面页数 PanelText.text = string.Format("{0}/{1}", PageIndex.ToString(), PageCount.ToString()); } /// <summary> /// 绑定页数方法 /// </summary> /// <param name="当前页码"></param> private void UpdateUI(int currentIndex) { //没有数据则直接return if (ItemsCount <= 0) { return; } for (int i = (PageIndex-1) * 4; i < ((PageIndex-1) * 4 + 4 > ItemsCount ? ItemsCount : (PageIndex-1) * 4 + 4); i++) { var needGameObject = Instantiate(gameObjectPrefab) as GameObject; needGameObject.transform.SetParent(ParentObj.transform); needGameObject.GetComponent<Image>().sprite = LoadSprite(items[i].ToString()); } } /// <summary> /// 删除对象下的子对象 /// </summary> /// <param name="父物体"></param> public void DestroyChildObject(GameObject parentObject) { if (parentObject == null) return; for (int i = parentObject.transform.childCount - 1; i >= 0; i--) { Destroy(parentObject.transform.GetChild(i).gameObject); } Resources.UnloadUnusedAssets(); } private Sprite LoadSprite(string assetName) { //资源文件一般放在Textures中 Texture texture = (Texture)Resources.Load("Textures/" + assetName); Sprite sprite = Sprite.Create((Texture2D)texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); return sprite; } }
实现效果:
Demo资源
这里是刚入职U3D的萌新一枚,日常记录工作遇到的问题以及解决方法,最近在学习strangIOC框架,有空的时候拿框架实现分页试试。
相关文章推荐
- 简单的瀑布流效果的实现—纯CSS和原生JS两种方式
- spring.net、castle windsor、unity实现aop、ioc的方式和简单区别
- Android实现简单的分页效果
- springmvc+jpa实现分页的两种方式
- 简单SQL语句实现分页效果
- SQL两种简单分页查询方式
- 智能指针的简单实现及两种误用方式
- 用Ext-4.2简单实现分页效果
- .NET中使用datagrid实现的简单分页效果
- js实现文件下载的两种简单方式
- Cocos2dx实现翻牌效果(CCScaleTo与CCOrbitCamera两种方式)
- Android-两种方式实现走马灯效果
- Android 跑马灯效果实现的两种方式,解决和viewpager的冲突问题
- jQuery图片无缝滑动效果的两种实现方式
- vue.js 组件实现简单分页效果
- unity中的简单水效果实现
- .NET中使用datagrid实现的简单分页效果
- 【Android UI设计与开发】第14期:顶部标题栏(五)两种方式实现仿微信标题栏弹窗效果
- 【Android UI设计与开发】第14期:顶部标题栏(五)两种方式实现仿微信标题栏弹窗效果
- SQL两种简单分页查询方式