unity實(shí)現(xiàn)翻頁按鈕功能
本文實(shí)例為大家分享了unity實(shí)現(xiàn)翻頁按鈕功能的具體代碼,供大家參考,具體內(nèi)容如下
效果圖:

UI子父級(jí)關(guān)系:

代碼中也都有加入注釋,有不懂可私信我。腳本中用到了對(duì)象池,我沒有上傳,可根據(jù)自己需求做相應(yīng)變動(dòng)。
腳本: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>
/// 頁數(shù)的父物體
/// </summary>
private RectTransform pageBtnParent;
private HorizontalLayoutGroup pageBtnParent_HLG;
/// <summary>
/// 上一頁按鈕點(diǎn)擊事件
/// </summary>
private UnityAction<int> lastPageBtnEvent;
/// <summary>
/// 下一頁按鈕點(diǎn)擊事件
/// </summary>
private UnityAction<int> nextPageBtnEvent;
/// <summary>
/// 當(dāng)前顯示頁面的下標(biāo)
/// </summary>
private int _currentShowPageIndex = 1;
public int CurrentShowPageIndex {
get {
return _currentShowPageIndex;
}
set {
_currentShowPageIndex = value;
}
}
/// <summary>
/// 總的頁面數(shù)
/// </summary>
private int totalPageNumber = 0;
/// <summary>
/// 顯示按鈕的個(gè)數(shù) 奇數(shù)個(gè)
/// </summary>
[Header("必須是奇數(shù)個(gè),且小于總頁數(shù)")]
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>
/// 頁數(shù)按鈕 預(yù)設(shè)體
/// </summary>
public GameObject btnPrefabs;
/// <summary>
/// 頁數(shù)按鈕 存放list
/// </summary>
public List<PageBtnC> pbcList;
private void Start()
{
Init();
Set(14, 9, (index1) =>
{
Debug.Log("當(dāng)前顯示第:" + CurrentShowPageIndex + "頁");
}, (index2) =>
{
Debug.Log("當(dāng)前顯示第:" + CurrentShowPageIndex + "頁");
}, (_pageIndex, _pbc) =>
{
Debug.Log("當(dāng)前顯示第:" + CurrentShowPageIndex + "頁");
});
}
/// <summary>
/// 改變顯示的狀態(tài)
/// </summary>
void ChangeShowState() {
int _showBtnCount = ShowBtnCount;
/*
判斷是否在可更新范圍內(nèi),如果在更新范圍內(nèi),則將CurrentShowPageIndex設(shè)置為中心位置的按鈕
eg:假設(shè)總共有10頁(totalPageNumber = 10),顯示按鈕的個(gè)數(shù)為7(ShowBtnCount = 7)
則應(yīng)該在 (ShowBtnCount / 2 + 1) = 4 到 totalPageNumber - ShowBtnCount / 2 = 7 之間設(shè)置
如果CurrentShowPageIndex = 5或6
則應(yīng)該這樣顯示 1.. 3 4 5 6 7 ..10
如果不在更新范圍內(nèi),
如果CurrentShowPageIndex = 1或2或3或4 則應(yīng)該這樣顯示: 1 2 3 4 5 6 ..10
如果如果CurrentShowPageIndex = 7或8或9或10 則應(yīng)該這樣顯示 1.. 5 6 7 8 9 10
*/
if (CurrentShowPageIndex >= (ShowBtnCount / 2 + 1) && CurrentShowPageIndex <= (totalPageNumber - ShowBtnCount / 2))
{
int _showBtnCount2 = _showBtnCount - 2;
_showBtnCount2 /= 2;
//判斷起始下標(biāo)
int startIndex = CurrentShowPageIndex - _showBtnCount2;
int endIndex = CurrentShowPageIndex + _showBtnCount2;
//防止超出
if (startIndex <= 1)
{
startIndex = 2;
}
//防止超出
if (endIndex >= totalPageNumber)
{
endIndex = totalPageNumber - 1;
}
//計(jì)算中心位置按鈕的下標(biāo) 因?yàn)閟howBtnCount不定
int centerIndex = ShowBtnCount / 2;
pbcList[centerIndex].Set(CurrentShowPageIndex);
//循環(huán)設(shè)置前面一部分按鈕信息
for (int i = 1; i < centerIndex; i++)
{
pbcList[i].Set(startIndex++);
}
//循環(huán)設(shè)置后面一部分按鈕信息
for (int i = centerIndex + 1; i < ShowBtnCount - 1; i++)
{
startIndex++;
pbcList[i].Set(startIndex);
}
}
else {
//如果點(diǎn)擊的是小于等于4的按鈕下標(biāo)
if (CurrentShowPageIndex < (ShowBtnCount / 2 + 1))
{
for (int i = 0; i < ShowBtnCount - 1; i++) {
pbcList[i].Set(i+1);
}
}//如果點(diǎn)擊的事大于等于7的按鈕下標(biāo)
else if (CurrentShowPageIndex > (totalPageNumber - ShowBtnCount / 2)) {
int startNumber = totalPageNumber - ShowBtnCount + 2;
for (int i = 1; i < ShowBtnCount; i++) {
pbcList[i].Set(startNumber++);
}
}
}
/*
判斷總顯示頁數(shù)是否大于顯示頁數(shù)
以防止出現(xiàn)這種效果:
例如:totalPageNumber = 7,ShowBtnCount =7
防止出現(xiàn)的效果:1 2 3 4 5 6 ..7 和 1.. 2 3 4 5 6 7
應(yīng)該出現(xiàn)的效果: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>
/// 設(shè)置信息
/// </summary>
/// <param name="totalPageNumber">總頁數(shù)</param>
/// <param name="showBtnCount">顯示多少個(gè)按鈕,填奇數(shù),如果填偶數(shù),則會(huì)強(qiáng)制減1,如:填6,則實(shí)際為5</param>
/// <param name="lastBtnEvent">上一頁按鈕事件</param>
/// <param name="nextBtnEvent">下一頁按鈕事件</param>
/// <param name="pageBtnClickEvent">單獨(dú)點(diǎn)擊頁面按鈕事件</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>
/// 重置所有按鈕的狀態(tài)
/// </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>
/// 根據(jù)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>
/// 設(shè)置物體寬度 子物體寬度相同
/// </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>
/// 設(shè)置物體寬度 子物體寬度不同
/// </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>
/// 設(shè)置正常顏色
/// </summary>
public void SetNormalColor() {
img.color = normalColor;
selfText.color = normalTextColor;
}
/// <summary>
/// 設(shè)置高亮顏色
/// </summary>
public void SetHighlightColor() {
img.color = highlightColor;
selfText.color = highlightTextColor;
}
/// <summary>
/// 設(shè)置事件 文本內(nèi)容等
/// </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 對(duì)象池接口方法
public int GetMaxCount()
{
return 10;
}
public string SingletonName()
{
return this.GetType().Name;
}
public void Spawn()
{
Init();
}
public void UnSpawn()
{
SetNormalColor();
}
#endregion
}
github地址
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解c# 強(qiáng)制轉(zhuǎn)換和類型轉(zhuǎn)換
這篇文章主要介紹了c# 強(qiáng)制轉(zhuǎn)換和類型轉(zhuǎn)換的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下2020-10-10
C#實(shí)現(xiàn)順序隊(duì)列和鏈隊(duì)列的代碼實(shí)例
今天小編就為大家分享一篇關(guān)于C#實(shí)現(xiàn)順序隊(duì)列和鏈隊(duì)列的代碼實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10
C#環(huán)形隊(duì)列的實(shí)現(xiàn)方法詳解
這篇文章先是簡(jiǎn)單的給大家介紹了什么是環(huán)形隊(duì)列和環(huán)形隊(duì)列的優(yōu)點(diǎn),然后通過實(shí)例代碼給大家介紹C#如何實(shí)現(xiàn)環(huán)形隊(duì)列,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-09-09
C# WinForm制作登錄界面的實(shí)現(xiàn)步驟
本文主要介紹了C# WinForm制作登錄界面的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
使用Linq注意事項(xiàng)避免報(bào)錯(cuò)的方法
這篇文章主要介紹了使用Linq注意事項(xiàng)避免報(bào)錯(cuò)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01

