目录
Unity UGUI 效果 之 多页翻页,多页任意翻页的简单效果实现(示例演示为动态加载多图片实现翻页预览效果)
一、简单介绍
二、实现原理
三、注意事项
四、效果预览
六、关键代码
七、参考工程
UGUI,是Unity自带的 GUI 系统,有别于 NGUI;使用 UGUI 也能制作出比较酷炫的效果 。
本节介绍,使用 UGUI 通过代码实现多页翻页的效果,示例是以动态加载图片为例实现的多页翻页效果。
1、通过展示的总的动态图片个书,每页每页展示图片的数量,分为若干页
2、Button实现前后翻页,Toggle 实现任意翻页
3、关键的逻辑代码是当前页时,代码实现展示的内容
1、在计算分页总页数的时候,注意整除和右余数的时候,总页数是不一样的
2、前后翻页和任意翻页都要互相更新显示
3、代码 toggle.isOn 的时候,是不会触发对应的监听时间函数,请注意
4、多说一句,在加载图片展示的时候,最好不要一张一张边加载,边展示,这样很有可能会程序崩溃;多图多的话,分批多次加载,一批加载完,展示一批
5、图片加载的路径(pageIconPath = @"D:\Tmp\Images"),是我本机的图片位置,代码中记得更改为自己的图片路径
五、实现步骤
1、打开 Unity ,新建空工程
2、在场景中布局 UGUI ,PageItem 和 MultiPageToggleItem 会作为预制体,用于动态加载
3、在工程中新建脚本,编辑脚本,实现相关逻辑代码
4、把脚本对应挂载,并赋值
5、运行场景,效果如上
1、MultiPageShowWrapper.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class MultiPageShowWrapper : MonoBehaviour
{
#region 常量
// Page Icon 加载路径
const string pageIconPath = @"D:\Tmp\Images";
// PageItem Resources 加载路径
const string PageItemPath = @"PageItem";
// MultiPageToggleItem Resources 加载路径
const string MultiPageToggleItemPath = @"MultiPageToggleItem";
// 每页展示 icon 的数量
const int ShowPageIconItemCountPerPage = 10;
#endregion
#region 字段
// 生成显示放置 PageItem 的父物体
public Transform PageGrid_Image;
// 生成显示放置 MultiPageToggleItem 的父物体
public Transform PageToggleGroup;
// 左翻页按钮
public Button LeftPage_Button;
// 右翻页按钮
public Button RightPage_Button;
// 当前页/总页显示文本
public Text PageCount_Text;
// PageItem 物体
GameObject mPageItem;
// MultiPageToggleItem 物体
GameObject mMultiPageToggleItem;
// Page ICon 图片路径的列表
private List mPageIconList = new List();
private int currentPage = 0;
private int totalPage = 0;
private int currentIntiateItem = 0;
private int PageIconListCount = 0;
#endregion
#region 方法
#region 其他视情况而定的方法 协程加载指定路径的图片
private List mPageIconTextureList = new List();
int loadIndex = 0;
bool isLoadedEnd = false;
void InitLoadIconTexture2d()
{
mPageIconList = GetWindiowsPCPicturesPath.GetPictutresPathsInTheFilePath(pageIconPath);
for (int i = 0; i < mPageIconList.Count; i++)
{
loadIndex++;
GetTexture(mPageIconList[i], (texture2D) =>
{
loadIndex--;
mPageIconTextureList.Add(texture2D);
});
}
}
void Start()
{
InitLoadIconTexture2d();
}
void Update() {
if (mPageIconTextureList.Count>0 && loadIndex <=0 && isLoadedEnd == false)
{
isLoadedEnd = true;
StartCoroutine(ShowPageIconList(mPageIconTextureList));
}
}
///
/// 请求图片
///
/// 图片地址,like 'http://www.my-server.com/image.png '
/// 请求发起后处理回调结果的委托,处理请求结果的图片
///
public void GetTexture(string url, Action actionResult)
{
StartCoroutine(_GetTexture(url, actionResult));
}
///
/// 请求图片
///
/// 图片地址,like 'http://www.my-server.com/image.png '
/// 请求发起后处理回调结果的委托,处理请求结果的图片
///
IEnumerator _GetTexture(string url, Action actionResult)
{
UnityWebRequest uwr = new UnityWebRequest(url);
DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
uwr.downloadHandler = downloadTexture;
yield return uwr.SendWebRequest();
Texture2D t = null;
if (!(uwr.isNetworkError || uwr.isHttpError))
{
t = downloadTexture.texture;
}
else
{
Debug.Log("下载失败,请检查网络,或者下载地址是否正确 ");
}
if (actionResult != null)
{
actionResult(t);
}
}
#endregion
///
/// 加載 PageItem
///
///
private GameObject LoadAppItem()
{
GameObject tmp = Resources.Load(PageItemPath);
if (tmp == null)
{
Debug.LogError("AppItem Load Failure!! AppItemPath may be Error.");
return null;
}
return tmp;
}
///
/// 加載 MultiPageToggleItem
///
///
private GameObject LoadMultiPageToggleItem()
{
GameObject tmp = Resources.Load(MultiPageToggleItemPath);
if (tmp == null)
{
Debug.LogError("AppItem Load Failure!! AppCountToggleItemPath may be Error.");
return null;
}
return tmp;
}
///
/// 展示 Page Icon 列表
/// 注意 有考虑到数据动态的怎加或减少的情况
///
///
///
private IEnumerator ShowPageIconList(List pageIconTextureList)
{
yield return new WaitForEndOfFrame();
PageIconListCount = pageIconTextureList.Count;
mPageIconTextureList = pageIconTextureList;
#region 当前页数和总页数
// 设置初始当前页为 1
currentPage = 1;
// 判断总数量是否整除每页数量 (有余则总页数+1,整除则不用)
totalPage = (int)(PageIconListCount / ShowPageIconItemCountPerPage) + (((PageIconListCount % ShowPageIconItemCountPerPage) == 0) ? 0 : 1);
#endregion
#region 底部任意切换页数的UI Toggel 显示生成
// Page Toggle (底部任意切换页数的UI Toggel 显示生成)
HideMultiPageToggleItems();
if (PageToggleGroup.childCount >= totalPage)
{
for (int i = 0; i < totalPage; i++)
{
MultiPageToggleItem multiPageToggleItem = PageToggleGroup.GetChild(i).GetComponent();
SetMultiPageToggleItemData(i, multiPageToggleItem);
multiPageToggleItem.gameObject.SetActive(true);
}
}
else
{
for (int i = 0; i < PageToggleGroup.childCount; i++)
{
MultiPageToggleItem multiPageToggleItem = PageToggleGroup.GetChild(i).GetComponent();
SetMultiPageToggleItemData(i, multiPageToggleItem);
multiPageToggleItem.gameObject.SetActive(true);
}
// 之前生成不够数量的 multiPageToggleItem 则生成
for (int i = PageToggleGroup.childCount; i < totalPage; i++)
{
MultiPageToggleItem multiPageToggleItem = GameObject.Instantiate(mMultiPageToggleItem).GetComponent();
SetMultiPageToggleItemData(i, multiPageToggleItem);
}
}
#endregion
#region Page Icon 的展示
// Page Item (Page Icon 的展示(原理同上类似))
currentIntiateItem = PageGrid_Image.childCount;
if (PageIconListCount < ShowPageIconItemCountPerPage)
{
// 隱藏所有,保障多餘的不會顯示
HidePageItems();
}
// 展示已有的不必重新生成的對象(currentIntiateItem 不會超過ShowAppItemCountPerPage)
for (int i = 0; i < currentIntiateItem; i++)
{
if (PageIconListCount < currentIntiateItem)
{
if (i == PageIconListCount)
{
break;
}
}
PageItem pageItem = PageGrid_Image.GetChild(i).GetComponent();
pageItem.gameObject.SetActive(true);
SetPageItemData(i, pageIconTextureList, pageItem);
}
// App總數大於生成的 生成的小於 ShowAppItemCountPerPage 個
// 1、App總數大於 ShowAppItemCountPerPage
// 2、App總數小於等於 ShowAppItemCountPerPage
if (PageIconListCount > currentIntiateItem)
{
if (ShowPageIconItemCountPerPage < PageIconListCount)
{
for (int i = currentIntiateItem; i < ShowPageIconItemCountPerPage; i++)
{
PageItem pageItem = Instantiate(mPageItem).GetComponent();
SetPageItemData(i, pageIconTextureList, pageItem);
}
}
else
{
for (int i = currentIntiateItem; i < PageIconListCount; i++)
{
PageItem pageItem = Instantiate(mPageItem).GetComponent();
SetPageItemData(i, pageIconTextureList, pageItem);
}
}
}
#endregion
#region 页数和翻页按钮的更新
//更新頁碼
PageCount_Text.text = currentPage + "/" + totalPage;
// 最前頁,把左翻頁隱藏
LeftPage_Button.gameObject.SetActive(false);
// 只有一页,右翻页也隐藏
if (totalPage == 1)
{
RightPage_Button.gameObject.SetActive(false);
}
#endregion
}
#region 左右翻页操作数据显示
///
/// 向前(左)翻頁
///
private void LeftPageEvent()
{
// 最前一頁,不能左翻頁
if ((currentPage) == 1)
{
return;
}
else
{
// 向左翻頁 右翻頁若隱藏即可顯示
if (RightPage_Button.gameObject.activeSelf == false)
{
RightPage_Button.gameObject.SetActive(true);
}
currentPage = currentPage - 1;
// Toggle 更新 (这里不会主动调用 toggle 事件,所以放心不用重复操作数据)
PageToggleGroup.GetChild(currentPage - 1).GetComponent().SetToggleIsOn(true);
// 最前頁,把左翻頁隱藏
if (currentPage == 1)
{
LeftPage_Button.gameObject.SetActive(false);
}
// 刷新展示
int startInt = ((currentPage - 1) * ShowPageIconItemCountPerPage);
for (int i = 0; i < ShowPageIconItemCountPerPage; i++)
{
PageItem pageItem = PageGrid_Image.GetChild(i).GetComponent();
pageItem.gameObject.SetActive(true);
SetPageItemData(startInt + i, mPageIconTextureList, pageItem);
}
}
//更新頁碼
PageCount_Text.text = currentPage + "/" + totalPage;
}
///
/// 向后(右)翻頁
///
private void RightPageEvent()
{
// 最后一頁,不能右翻頁
if ((currentPage) == totalPage)
{
return;
}
else
{
// 向右翻頁 左翻頁若隱藏即可顯示
if (LeftPage_Button.gameObject.activeSelf == false)
{
LeftPage_Button.gameObject.SetActive(true);
}
currentPage = currentPage + 1;
// Toggle 更新 (这里不会主动调用 toggle 事件)
PageToggleGroup.GetChild(currentPage - 1).GetComponent().SetToggleIsOn(true);
int startInt = ((currentPage - 1) * ShowPageIconItemCountPerPage);
// 翻到最后一頁(可能不是10個,要計算展示個數)
if (currentPage == (totalPage))
{
// 隱藏所有,保障多餘的不會顯示
HidePageItems();
int endInt = PageIconListCount - startInt;
for (int i = 0; i < endInt; i++)
{
PageItem pageItem = PageGrid_Image.GetChild(i).GetComponent();
pageItem.gameObject.SetActive(true);
SetPageItemData(startInt + i, mPageIconTextureList, pageItem);
}
// 把右翻頁隱藏
RightPage_Button.gameObject.SetActive(false);
}
else
{ // 翻到不是最后一頁(10個展示即可)
for (int i = 0; i < ShowPageIconItemCountPerPage; i++)
{
PageItem pageItem = PageGrid_Image.GetChild(i).GetComponent();
pageItem.gameObject.SetActive(true);
SetPageItemData(startInt + i, mPageIconTextureList, pageItem);
}
}
}
//更新頁碼
PageCount_Text.text = currentPage + "/" + totalPage;
}
#endregion
#region Toggle 翻页数据(这里有底部(子) MultiPageToggleItem 发送消息调用)
///
/// Toggle翻页
///
///
public void ToggelPageEvent(int page)
{
if (currentPage == page)
{
return;
}
currentPage = page;
// 最前頁,把左翻頁隱藏
if (currentPage == 1)
{
LeftPage_Button.gameObject.SetActive(false);
}
else
{
LeftPage_Button.gameObject.SetActive(true);
}
if (currentPage == totalPage)
{
// 把右翻頁隱藏
RightPage_Button.gameObject.SetActive(false);
}
else
{
RightPage_Button.gameObject.SetActive(true);
}
int startInt = ((currentPage - 1) * ShowPageIconItemCountPerPage);
// 翻到最后一頁(可能不是10個,要計算展示個數)
if (currentPage == (totalPage))
{
// 隱藏所有,保障多餘的不會顯示
HidePageItems();
int endInt = PageIconListCount - startInt;
for (int i = 0; i < endInt; i++)
{
PageItem pageItem = PageGrid_Image.GetChild(i).GetComponent();
pageItem.gameObject.SetActive(true);
SetPageItemData(startInt + i, mPageIconTextureList, pageItem);
}
}
else
{ // 翻到不是最后一頁(10個展示即可)
for (int i = 0; i < ShowPageIconItemCountPerPage; i++)
{
PageItem pageItem = PageGrid_Image.GetChild(i).GetComponent();
pageItem.gameObject.SetActive(true);
SetPageItemData(startInt + i, mPageIconTextureList, pageItem);
}
}
//更新頁碼
PageCount_Text.text = currentPage + "/" + totalPage;
}
#endregion
///
/// 设置生成的 pageItem 的数据
///
///
///
///
private void SetPageItemData(int i, List pageIconlist, PageItem pageItem)
{
pageItem.transform.SetParent(PageGrid_Image, false);
pageItem.transform.localScale = Vector3.one;
pageItem.IconTexture = pageIconlist[i];
}
///
/// 设置 MultiPageToggleItem 实体数据信息
///
///
///
private void SetMultiPageToggleItemData(int i, MultiPageToggleItem multiPageToggleItem)
{
multiPageToggleItem.transform.SetParent(PageToggleGroup, false);
multiPageToggleItem.transform.localScale = Vector3.one;
multiPageToggleItem.Page = i + 1;
multiPageToggleItem.SetToggleGroup(PageToggleGroup.GetComponent());
// 为了默认第一个 toggle 是 isOn 显示的(预制体要提前 false)
if (i != 0)
{
multiPageToggleItem.SetToggleIsOn(false);
}
else
{
multiPageToggleItem.SetToggleIsOn(true);
}
}
///
/// 隐藏 PageToggleGroup 下所有 MultiPageToggleItem 实体
///
private void HideMultiPageToggleItems()
{
for (int i = 0; i < PageToggleGroup.childCount; i++)
{
PageToggleGroup.GetChild(i).gameObject.SetActive(false);
}
}
///
/// 隐藏 PageGrid_Image 下所有 PageItem 实体
///
private void HidePageItems()
{
for (int i = 0; i < PageGrid_Image.childCount; i++)
{
PageGrid_Image.GetChild(i).gameObject.SetActive(false);
}
}
#endregion
#region Unity回调
///
/// Awake this instance.
///
void Awake()
{
// 下載 AppItem
mPageItem = LoadAppItem();
mMultiPageToggleItem = LoadMultiPageToggleItem();
// 綁定左右翻页的监听事件
LeftPage_Button.onClick.AddListener(LeftPageEvent);
RightPage_Button.onClick.AddListener(RightPageEvent);
}
private void OnEnable()
{
//StartCoroutine(ShowPageIconList( GetWindiowsPCPicturesPath.GetPictutresPathsInTheFilePath(pageIconPath)));
}
#endregion
}
2、PageItem.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class PageItem : MonoBehaviour
{
public RawImage Icon_RawImage;
// 字段
private Texture2D iconTexture;
private string iconpath;
// 属性
public Texture2D IconTexture { get => iconTexture;
set {
iconTexture = value;
if (Icon_RawImage != null)
{
Icon_RawImage.texture = iconTexture;
}
}
}
public string Iconpath { get => iconpath; set {
iconpath = value;
GetTexture(iconpath,(texture2d)=> {
IconTexture = texture2d;
});
}
}
#region 其他视情况而定的方法 协程加载指定路径的图片 (注意:动态多图加载,这种方式很有可能会让程序奔溃)
///
/// 请求图片
///
/// 图片地址,like 'http://www.my-server.com/image.png '
/// 请求发起后处理回调结果的委托,处理请求结果的图片
///
public void GetTexture(string url, Action actionResult)
{
StartCoroutine(_GetTexture(url, actionResult));
}
///
/// 请求图片
///
/// 图片地址,like 'http://www.my-server.com/image.png '
/// 请求发起后处理回调结果的委托,处理请求结果的图片
///
IEnumerator _GetTexture(string url, Action actionResult)
{
UnityWebRequest uwr = new UnityWebRequest(url);
DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
uwr.downloadHandler = downloadTexture;
yield return uwr.SendWebRequest();
Texture2D t = null;
if (!(uwr.isNetworkError || uwr.isHttpError))
{
t = downloadTexture.texture;
}
else
{
Debug.Log("下载失败,请检查网络,或者下载地址是否正确 ");
}
if (actionResult != null)
{
actionResult(t);
}
}
#endregion
}
3、MultiPageToggleItem.cs
using UnityEngine;
using UnityEngine.UI;
public class MultiPageToggleItem : MonoBehaviour
{
public Toggle MultiPage_Toggle;
private int page;
public int Page { get => page; set => page = value; }
// Start is called before the first frame update
void Start()
{
// 绑定事件
MultiPage_Toggle.onValueChanged.AddListener((isOn) => {
if (isOn == true)
{
Debug.Log("发送消息 ToggelPageEvent " + Page);
SendMessageUpwards("ToggelPageEvent", Page);
}
});
}
///
/// 设置 ToggleGroup
///
///
public void SetToggleGroup(ToggleGroup toggleGroup)
{
MultiPage_Toggle.group = toggleGroup;
}
///
/// 设置 isON
///
///
public void SetToggleIsOn(bool isOn)
{
MultiPage_Toggle.isOn = isOn;
}
}
4、GetWindiowsPCPicturesPath.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.IO;
using UnityEngine;
public class GetWindiowsPCPicturesPath {
public static void DebugPaths() {
List filePaths = GetPictutresPathsInTheFilePath(@"D:\Tmp\Images");
for (int i = 0; i < filePaths.Count; i++)
{
Debug.Log(filePaths[i]);
}
}
///
/// win 中获取指定文件夹下的图片,不包括子文件夹的图片
///
///
/// 图片路径集合列表
public static List GetPictutresPathsInTheFilePath(string filePath)
{
List filePaths = new List();
string imgtype = "*.BMP|*.JPG|*.GIF|*.PNG";
string[] ImageType = imgtype.Split('|');
for (int i = 0; i < ImageType.Length; i++)
{
//获取指定文件夹下所有的图片路径
string[] dirs = Directory.GetFiles(filePath, ImageType[i]);
for (int j = 0; j < dirs.Length; j++)
{
filePaths.Add(dirs[j]);
}
}
return filePaths;
}
}
下载地址:https://download.csdn.net/download/u014361280/12639147