您的位置:首页 > 移动开发 > Unity3D

用两种简单的方式实现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框架,有空的时候拿框架实现分页试试。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: