unity实现翻页按钮功能

作者:贪玩的孩纸时代 时间:2021-07-15 03:33:47 

本文实例为大家分享了unity实现翻页按钮功能的具体代码,供大家参考,具体内容如下

效果图:

unity实现翻页按钮功能

UI子父级关系:

unity实现翻页按钮功能

代码中也都有加入注释,有不懂可私信我。脚本中用到了对象池,我没有上传,可根据自己需求做相应变动。

脚本:PageBtnPanelC


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
/// <summary>
/// 分页按钮面板控制器
/// </summary>
public class PageBtnPanelC : MonoBehaviour {
private HorizontalLayoutGroup self_HLG;
/// <summary>
/// 上一页按钮
/// </summary>
private Button lastPageBtn;
/// <summary>
/// 下一页按钮
/// </summary>
private Button nextPageBtn;
/// <summary>
/// 页数的父物体
/// </summary>
private RectTransform pageBtnParent;
private HorizontalLayoutGroup pageBtnParent_HLG;
/// <summary>
/// 上一页按钮点击事件
/// </summary>
private UnityAction<int> lastPageBtnEvent;
/// <summary>
/// 下一页按钮点击事件
/// </summary>
private UnityAction<int> nextPageBtnEvent;
/// <summary>
/// 当前显示页面的下标
/// </summary>
private int _currentShowPageIndex = 1;
public int CurrentShowPageIndex {
 get {
  return _currentShowPageIndex;
 }
 set {
  _currentShowPageIndex = value;
 }
}
/// <summary>
/// 总的页面数
/// </summary>
private int totalPageNumber = 0;
/// <summary>
/// 显示按钮的个数 奇数个
/// </summary>
[Header("必须是奇数个,且小于总页数")]
private int _showBtnCount = 5;
public int ShowBtnCount {
 get {
  if (_showBtnCount > totalPageNumber) {
   _showBtnCount = totalPageNumber;
  }

return _showBtnCount;
 }
 set {
  if (value % 2 == 0)
  {
   _showBtnCount = value - 1;
  }
  else {
   _showBtnCount = value;
  }
 }
}
/// <summary>
/// 页数按钮 预设体
/// </summary>
public GameObject btnPrefabs;
/// <summary>
/// 页数按钮 存放list
/// </summary>
public List<PageBtnC> pbcList;

private void Start()
{
 Init();
 Set(14, 9, (index1) =>
 {
  Debug.Log("当前显示第:" + CurrentShowPageIndex + "页");
 }, (index2) =>
 {
  Debug.Log("当前显示第:" + CurrentShowPageIndex + "页");
 }, (_pageIndex, _pbc) =>
 {
  Debug.Log("当前显示第:" + CurrentShowPageIndex + "页");
 });
}
/// <summary>
/// 改变显示的状态
/// </summary>
void ChangeShowState() {
 int _showBtnCount = ShowBtnCount;
 /*
  判断是否在可更新范围内,如果在更新范围内,则将CurrentShowPageIndex设置为中心位置的按钮
  eg:假设总共有10页(totalPageNumber = 10),显示按钮的个数为7(ShowBtnCount = 7)
  则应该在 (ShowBtnCount / 2 + 1) = 4 到 totalPageNumber - ShowBtnCount / 2 = 7 之间设置
  如果CurrentShowPageIndex = 5或6
  则应该这样显示  1.. 3 4 5 6 7 ..10
  如果不在更新范围内,
  如果CurrentShowPageIndex = 1或2或3或4  则应该这样显示: 1 2 3 4 5 6 ..10
  如果如果CurrentShowPageIndex = 7或8或9或10 则应该这样显示 1.. 5 6 7 8 9 10
  */
 if (CurrentShowPageIndex >= (ShowBtnCount / 2 + 1) && CurrentShowPageIndex <= (totalPageNumber - ShowBtnCount / 2))
 {
  int _showBtnCount2 = _showBtnCount - 2;
  _showBtnCount2 /= 2;

//判断起始下标
  int startIndex = CurrentShowPageIndex - _showBtnCount2;
  int endIndex = CurrentShowPageIndex + _showBtnCount2;

//防止超出
  if (startIndex <= 1)
  {
   startIndex = 2;
  }
  //防止超出
  if (endIndex >= totalPageNumber)
  {
   endIndex = totalPageNumber - 1;
  }

//计算中心位置按钮的下标 因为showBtnCount不定
  int centerIndex = ShowBtnCount / 2;

pbcList[centerIndex].Set(CurrentShowPageIndex);

//循环设置前面一部分按钮信息
  for (int i = 1; i < centerIndex; i++)
  {
   pbcList[i].Set(startIndex++);
  }

//循环设置后面一部分按钮信息
  for (int i = centerIndex + 1; i < ShowBtnCount - 1; i++)
  {
   startIndex++;
   pbcList[i].Set(startIndex);
  }
 }
 else {
  //如果点击的是小于等于4的按钮下标
  if (CurrentShowPageIndex < (ShowBtnCount / 2 + 1))
  {
   for (int i = 0; i < ShowBtnCount - 1; i++) {
    pbcList[i].Set(i+1);
   }
  }//如果点击的事大于等于7的按钮下标
  else if (CurrentShowPageIndex > (totalPageNumber - ShowBtnCount / 2)) {

int startNumber = totalPageNumber - ShowBtnCount + 2;

for (int i = 1; i < ShowBtnCount; i++) {
    pbcList[i].Set(startNumber++);
   }
  }
 }

/*
  判断总显示页数是否大于显示页数
  以防止出现这种效果:
  例如:totalPageNumber = 7,ShowBtnCount =7
  防止出现的效果:1 2 3 4 5 6 ..7 和 1.. 2 3 4 5 6 7
  应该出现的效果:1 2 3 4 5 6 7
  */
 if (totalPageNumber > ShowBtnCount){
  _showBtnCount -= 2;
  _showBtnCount /= 2;
  if (CurrentShowPageIndex - _showBtnCount - 1 > 1)
  {
   pbcList[0].Set(1, "1..");
  }
  else
  {
   pbcList[0].Set(1);
  }
  if (CurrentShowPageIndex + _showBtnCount + 1 < totalPageNumber)
  {
   pbcList[ShowBtnCount - 1].Set(totalPageNumber, ".." + totalPageNumber);
  }
  else
  {
   pbcList[ShowBtnCount - 1].Set(totalPageNumber);
  }
 }
}

private bool isInit = false;
public void Init() {
 if (isInit)
  return;
 isInit = true;

pbcList = new List<PageBtnC>();

self_HLG = transform.GetComponent<HorizontalLayoutGroup>();

pageBtnParent = transform.Find("PageIndexParent") as RectTransform;
 pageBtnParent_HLG = pageBtnParent.GetComponent<HorizontalLayoutGroup>();

lastPageBtn = transform.Find("LastPageBtn").GetComponent<Button>();
 lastPageBtn.onClick.AddListener(()=> {
  if (totalPageNumber <= 0)
   return;

if (CurrentShowPageIndex > 1) {
   CurrentShowPageIndex--;
  }

ResetPageBtnState();

ChangeShowState();

PageBtnC pbc = GetPBCFromIndex(CurrentShowPageIndex);
  if (pbc != null) {
   pbc.SetHighlightColor();
  }

if (lastPageBtnEvent != null)
  {
   lastPageBtnEvent(CurrentShowPageIndex);
  }
 });

nextPageBtn = transform.Find("NextPageBtn").GetComponent<Button>();
 nextPageBtn.onClick.AddListener(()=> {
  if (totalPageNumber <= 0)
   return;

if (CurrentShowPageIndex < totalPageNumber) {
   CurrentShowPageIndex++;
  }

ResetPageBtnState();

ChangeShowState();

PageBtnC pbc = GetPBCFromIndex(CurrentShowPageIndex);
  if (pbc != null)
  {
   pbc.SetHighlightColor();
  }

if (nextPageBtnEvent != null)
  {
   nextPageBtnEvent(CurrentShowPageIndex);
  }

});
}
/// <summary>
/// 设置信息
/// </summary>
/// <param name="totalPageNumber">总页数</param>
/// <param name="showBtnCount">显示多少个按钮,填奇数,如果填偶数,则会强制减1,如:填6,则实际为5</param>
/// <param name="lastBtnEvent">上一页按钮事件</param>
/// <param name="nextBtnEvent">下一页按钮事件</param>
/// <param name="pageBtnClickEvent">单独点击页面按钮事件</param>
public void Set(int totalPageNumber,int showBtnCount,UnityAction<int> lastBtnEvent,UnityAction<int> nextBtnEvent,UnityAction<int,PageBtnC> pageBtnClickEvent) {
 if (totalPageNumber <= 0)
 {
  this.totalPageNumber = 1;
 }
 else {
  this.totalPageNumber = totalPageNumber;
 }

this.ShowBtnCount = showBtnCount;

this.lastPageBtnEvent = lastBtnEvent;
 this.nextPageBtnEvent = nextBtnEvent;

CurrentShowPageIndex = 1;

pbcList.Clear();

for (int i = 1; i <= ShowBtnCount; i++) {
  int index = i;
  PageBtnC pbc = PoolManager.Instance.Spawn(btnPrefabs, pageBtnParent).GetComponent<PageBtnC>();
  if (pbc) {
   pbc.Set(index,null, (pageIndex,pbc111) =>
   {
    CurrentShowPageIndex = pageIndex;

ResetPageBtnState();

ChangeShowState();

PageBtnC pbc1 = GetPBCFromIndex(CurrentShowPageIndex);
    if (pbc1 != null)
    {
     pbc1.SetHighlightColor();
    }
    if (pageBtnClickEvent != null) {
     pageBtnClickEvent(pageIndex, pbc111);
    }
   });
  }
  pbcList.Add(pbc);
 }

pbcList[0].SetHighlightColor();

ChangeShowState();

Util.SetWidth_ChildWidthSame(pageBtnParent_HLG, pageBtnParent);

Util.SetWidth_ChildWidthNotSame(self_HLG, transform as RectTransform);
}
/// <summary>
/// 重置所有按钮的状态
/// </summary>
void ResetPageBtnState() {
 for (int i = 0; i < pbcList.Count; i++) {
  pbcList[i].SetNormalColor();
 }
}
/// <summary>
/// 回收所有页码
/// </summary>
public void Unspawn() {
 for (int i = pageBtnParent.childCount - 1; i >= 0; i--) {

PoolManager.Instance.UnSpawn(pageBtnParent.GetChild(i).gameObject);
 }
}

public void Clear() {
 lastPageBtnEvent = null;
 nextPageBtnEvent = null;
}
/// <summary>
/// 根据index得到pagebtnc物体
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
PageBtnC GetPBCFromIndex(int index) {
 for (int i = 0; i < pbcList.Count; i++) {
  if (pbcList[i].CurrentPageIndex.Equals(index)) {
   return pbcList[i];
  }
 }

return null;
}
}

public class Util
{
/// <summary>
/// 设置物体宽度 子物体宽度相同
/// </summary>
/// <param name="parentHLG"></param>
/// <param name="parent"></param>
/// <param name="callback"></param>
public static void SetWidth_ChildWidthSame(HorizontalLayoutGroup parentHLG, RectTransform parent, UnityAction<float> endCallBack = null)
{
 float width = 0;

float leftPadding = parentHLG.padding.left;
 float spacing = parentHLG.spacing;

int childCount = parent.childCount;

if (childCount > 0)
 {
  RectTransform singleChildRT = parent.GetChild(0) as RectTransform;

width = childCount * singleChildRT.rect.width + (childCount - 1) * spacing + leftPadding;
 }

parent.sizeDelta = new Vector2(width, parent.sizeDelta.y);

if (endCallBack != null)
 {
  endCallBack(width);
 }
}

/// <summary>
/// 设置物体宽度 子物体宽度不同
/// </summary>
/// <param name="parentHLG"></param>
/// <param name="parent"></param>
/// <param name="callback"></param>
public static void SetWidth_ChildWidthNotSame(HorizontalLayoutGroup parentHLG, RectTransform parent, UnityAction<float> endCallBack = null)
{
 float width = 0;

RectOffset Padding = parentHLG.padding;
 float spacing = parentHLG.spacing;

int childCount = parent.childCount;

if (childCount > 0)
 {
  for (int i = 0; i < childCount; i++)
  {
   RectTransform childRT = parent.GetChild(i) as RectTransform;
   width += childRT.rect.width;
  }

width += (childCount - 1) * spacing + Padding.left + Padding.right;
 }

parent.sizeDelta = new Vector2(width, parent.sizeDelta.y);

if (endCallBack != null)
 {
  endCallBack(width);
 }
}
}

脚本:PageBtnC


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
/// <summary>
/// 页码按钮控制器
/// </summary>
public class PageBtnC : MonoBehaviour,IPool {
/// <summary>
/// 自己显示的页码
/// </summary>
private int currentPageIndex = 0;
public int CurrentPageIndex {
 get {
  return currentPageIndex;
 }
}

private Button SelfBtn;
private Image img;
private Text selfText;

/// <summary>
/// 按钮事件
/// </summary>
public UnityAction<int,PageBtnC> btnClickEvent;

/// <summary>
/// 按钮正常和高亮颜色
/// </summary>
public Color normalColor;
public Color highlightColor;

/// <summary>
/// 文本正常和高亮颜色
/// </summary>
public Color normalTextColor;
public Color highlightTextColor;

private bool isInit = false;
void Init() {
 if (isInit)
  return;
 isInit = true;

img = transform.GetComponent<Image>();

selfText = transform.Find("Text").GetComponent<Text>();

SelfBtn = transform.GetComponent<Button>();
 SelfBtn.onClick.AddListener(()=> {

if (btnClickEvent != null) {
   btnClickEvent(currentPageIndex,this);
  }
 });
}
/// <summary>
/// 设置正常颜色
/// </summary>
public void SetNormalColor() {
 img.color = normalColor;
 selfText.color = normalTextColor;
}
/// <summary>
/// 设置高亮颜色
/// </summary>
public void SetHighlightColor() {
 img.color = highlightColor;
 selfText.color = highlightTextColor;
}
/// <summary>
/// 设置事件 文本内容等
/// </summary>
/// <param name="currentPageIndex"></param>
/// <param name="selfTextStr"></param>
/// <param name="btnClickEvent"></param>
public void Set(int currentPageIndex,string selfTextStr = null,UnityAction<int,PageBtnC> btnClickEvent = null) {
 this.currentPageIndex = currentPageIndex;

if (btnClickEvent != null)
 {
  this.btnClickEvent = btnClickEvent;
 }

if (string.IsNullOrEmpty(selfTextStr))
 {
  selfText.text = currentPageIndex.ToString();
 }
 else {
  selfText.text = selfTextStr;
 }
}

#region 对象池接口方法
public int GetMaxCount()
{
 return 10;
}

public string SingletonName()
{
 return this.GetType().Name;
}

public void Spawn()
{
 Init();
}

public void UnSpawn()
{
 SetNormalColor();
}
#endregion
}

github地址

来源:https://blog.csdn.net/yiwei151/article/details/88406539

标签:unity,翻页,按钮
0
投稿

猜你喜欢

  • Android Studio多工程引用同一个library项目配置的解决方法

    2022-04-07 16:39:40
  • Android WebView基础应用详解

    2023-09-30 07:36:46
  • Android ViewModel创建不受横竖屏切换影响原理详解

    2023-08-31 21:21:20
  • Android 设置颜色的方法总结

    2023-12-14 16:41:57
  • C#中Dynamic和Dictionary性能比较

    2022-05-11 12:16:33
  • Android 快速实现防止网络重复请求&按钮重复点击的方法

    2023-08-29 17:31:45
  • C语言与C++中关于字符串使用的比较

    2022-01-22 01:30:37
  • MongoDB中ObjectId的误区及引起的一系列问题

    2023-06-16 09:46:00
  • 冒泡排序算法原理及JAVA实现代码

    2022-08-13 10:30:40
  • C#实现把图片转换成二进制以及把二进制转换成图片的方法示例

    2023-08-10 15:25:51
  • IDEA2020.2.3中创建JavaWeb工程的完整步骤记录

    2022-03-15 05:16:02
  • Android 正则表达式验证手机号、姓名(包含少数民族)、身份证号

    2022-05-26 02:17:11
  • VsCode使用EmmyLua插件调试Unity工程Lua代码的详细步骤

    2022-12-25 14:13:25
  • Adapter模式实战之重构鸿洋集团的Android圆形菜单建行

    2021-11-02 09:42:32
  • c#生成高清缩略图的二个示例分享

    2023-04-09 23:21:46
  • 基于ThreadLocal 的用法及内存泄露(内存溢出)

    2023-11-23 20:22:28
  • spring声明式事务 @Transactional 不回滚的多种情况以及解决方案

    2023-07-06 10:50:33
  • C#实现根据年份计算生肖属相的方法

    2023-04-01 01:12:06
  • C#异步使用需要注意的几个问题

    2023-03-05 04:33:08
  • springboot 参数格式校验操作

    2023-10-16 08:53:32
  • asp之家 软件编程 m.aspxhome.com