Unity 实现类似网页翻页效果

效果图

代码

using System.Collections.Generic;
using System.Linq;
using UniFramework.Event;
using UnityEngine;
using UnityEngine.UI;
using YooAsset;

/// <summary>
/// 翻页组件功能
/// </summary>
public class PageFlippingFunction : MonoBehaviour
{
    private readonly EventGroup _eventGroup = new EventGroup();

    private const string CONST_MORE = "···";
    private const float CONST_FLOAT1 = 45f;
    private const float CONST_FLOAT2 = 90f;
    private const string CONST_R = "r";
    private const string CONST_L = "l";
    private const string CONST_1 = "1";

    private Button _leftButton;
    private Button _rightButton;
    private InputField _gotoInputField;
    private Transform _buttons;

    private List<GameObject> _allNumButtons;

    private AssetHandle _pageNumButton;

    private int _currIndex;
    private int _currType;

    private WorkorderPageRequestData _workPageData;

    private void Awake()
    {
        _allNumButtons = new();
        _currIndex = 0;

        _pageNumButton = YooAssets.LoadAssetSync<GameObject>("Assets/Res/Prefabs/Workorder/PageNumButton");

        // 左翻页
        _leftButton = this.transform.Find("Page/Events/Buttons/LeftButton").GetComponent<Button>();
        _leftButton.onClick.AddListener(OnClickLeft);

        // 右翻页
        _rightButton = this.transform.Find("Page/Events/Buttons/RightButton").GetComponent<Button>();
        _rightButton.onClick.AddListener(OnClickRight);

        // 输入第几页
        _gotoInputField = this.transform.Find("Page/Events/Buttons/RightButton/Tail/InputFields/GotoInputField").GetComponent<InputField>();
        _gotoInputField.onValueChanged.AddListener((string v)=>OnClickGotoInput(v));

        // 前往第几页
        var gotoButton = this.transform.Find("Page/Events/Buttons/RightButton/Tail/Events/Buttons/GotoButton").GetComponent<Button>();
        gotoButton.onClick.AddListener(OnClickGoto);

        // 创建按钮的父节点
        _buttons = this.transform.Find("Page/Events/Buttons");

        _eventGroup.AddListener<WorkorderEventDefine.WorkorderPageUpdate>(OnHandleEventMessage);
    }
    private void OnHandleEventMessage(IEventMessage message)
    {
        if (message is WorkorderEventDefine.WorkorderPageUpdate)
        {
            var msg = message as WorkorderEventDefine.WorkorderPageUpdate;
            _workPageData = msg.Data as WorkorderPageRequestData;
            _workPageData.response.maxPage = _workPageData.response.total / 8 + ((_workPageData.response.total % 8 > 0) ? 1 : 0);

            Debug.Log(_workPageData.response.maxPage);
            RefreshPageGroup();
        }
    }

    private void RefreshPageGroup()
    {
        if (_workPageData.response.maxPage > 7)
        {
            if (_workPageData.response.pageNum > 4 && _workPageData.response.pageNum < _workPageData.response.maxPage - 3)
            {
                SetInputField(3);
            }
            else
            {
                if (_workPageData.response.pageNum <= 4)
                {
                    SetInputField(1);
                }
                else if (_workPageData.response.pageNum >= _workPageData.response.maxPage - 3)
                {
                    SetInputField(2);
                }
            }
        }
        else
        {
            SetInputField(1);
        }
    }

    private void OnClickLeft()
    {
        if(_currType == 2)
        {
            _currIndex++;
        }
        else
        {
            if (_currIndex == 0)
            {
                return;
            }
            _currIndex--;
        }
        NumListener(_currIndex);
    }

    private void OnClickRight()
    {
        if(_currType == 1 || _currType == 3)
        {
            _currIndex++;
        }
        else
        {
            if(_currIndex == 0)
            {
                return;
            }
            _currIndex--;
        }
        NumListener(_currIndex);
    }

    private void OnClickGotoInput(string v)
    {
        int value;
        if(!int.TryParse(v, out value))
        {
            _gotoInputField.text = "1";
            return;
        }
        if(value < 1)
        {
            _gotoInputField.text = "1";
        }
        else if(value > _workPageData.response.maxPage)
        {
            _gotoInputField.text = _workPageData.response.maxPage.ToString();
        }
    }

    private void OnClickGoto()
    {
        _workPageData.response.pageNum = int.Parse(_gotoInputField.text);
        ElectronicWorkInstance.GetInstance().DataRequestMessage(MessageCode.SET_CURR_WORKORDERPAGE, _workPageData.response.pageNum);
        WorkorderEventDefine.WorkorderJumpPage.SendEventMessage();
    }

    /// <summary>
    /// 1 右侧...
    /// 2 左侧...
    /// 3 两侧...
    /// </summary>
    /// <param name="type"></param>
    private void SetInputField(int type = 1)
    {
        _currType = type;
        for (int i = _allNumButtons.Count - 1; i >= 0; i--)
        {
            Destroy(_allNumButtons[i]);
        }
        _allNumButtons.Clear();
        int pageNumber = (_workPageData.response.maxPage > 7) ? 7 : _workPageData.response.maxPage;
        _leftButton.transform.localPosition = new Vector3(-(CONST_FLOAT2 + CONST_FLOAT1 * (pageNumber - 1)), 0, 0);
        _rightButton.transform.localPosition = new Vector3((CONST_FLOAT2 + CONST_FLOAT1 * (pageNumber - 1)), 0, 0);
        List<float> pointXs = CalculateWaveValues(pageNumber, type == 1 || type == 3);
        for (int i = 0; i < pointXs.Count; i++)
        {
            int index = i;
            Button button = (Instantiate(_pageNumButton.AssetObject, _buttons) as GameObject).GetComponent<Button>();
            Text text = button.transform.GetChild(0).GetComponent<Text>();
            if (_workPageData.response.maxPage > 7 && i == 5)
            {
                // 右边的...
                text.text = CONST_MORE;
                text.name = type == 1 || type == 3 ? CONST_R : CONST_L;
            }
            else if (_workPageData.response.maxPage > 7 && i == 6)
            {
                text.text = type == 1 || type == 3 ? _workPageData.response.maxPage.ToString() : text.text = CONST_1;
            }
            else if (type != 3)
            {
                text.text = type == 1 ? (i + 1).ToString() : (_workPageData.response.maxPage - i).ToString();
            }
            else if (_workPageData.response.maxPage > 7 && i == 1 && type == 3)
            {
                text.text = CONST_MORE;
                text.name = CONST_L;
            }
            else if (_workPageData.response.maxPage > 7 && i == 0 && type == 3)
            {
                text.text = CONST_1;
            }
            else if (type == 3)
            {
                text.text = (_workPageData.response.pageNum - 3 + i).ToString();
            }
            button.transform.localPosition = new Vector3(pointXs[i], 0, 0);
            button.onClick.AddListener(() => NumListener(index));
            _allNumButtons.Add(button.gameObject);
            if (_workPageData.response.pageNum == -1 && i == 0)
            {
                button.interactable = false;
                _currIndex = i;
            }
            else if (text.text != CONST_MORE && int.Parse(text.text) == _workPageData.response.pageNum)
            {
                button.interactable = false;
                _currIndex = i;
            }
        }
        if (_workPageData.response.pageNum == -1) _workPageData.response.pageNum = 1;
        _gotoInputField.text = _workPageData.response.pageNum.ToString();
    }
    private List<float> CalculateWaveValues(int pageNumber, bool sort)
    {
        float maxAmplitude = CONST_FLOAT1 * (pageNumber - 1);
        List<float> values = new List<float>();
        if (pageNumber == 1) return new List<float>() { 0 };
        for (int i = 0; i < pageNumber; i++)
        {
            float value = (i % 2 == 0) ? -maxAmplitude + (i / 2) * 2 * maxAmplitude / (pageNumber - 1) : maxAmplitude - ((i - 1) / 2) * 2 * maxAmplitude / (pageNumber - 1);
            values.Add(value);
        }
        return sort ? values.OrderBy(x => x).ToList() : values.OrderByDescending(x => x).ToList();
    }
    private void NumListener(int index)
    {
        _currIndex = index;
        Text text = _allNumButtons[index].transform.GetChild(0).GetComponent<Text>();
        string str = text.text;
        if (str == CONST_MORE)
        {
            if(text.name == CONST_R)
            {
                Text text2 = _allNumButtons[4].transform.GetChild(0).GetComponent<Text>();
                _workPageData.response.pageNum = int.Parse(text2.text) + 1;
            }
            else if(index == 1)
            {
                Text text2 = _allNumButtons[2].transform.GetChild(0).GetComponent<Text>();
                _workPageData.response.pageNum = int.Parse(text2.text) - 1;
            }
            else
            {
                Text text2 = _allNumButtons[4].transform.GetChild(0).GetComponent<Text>();
                _workPageData.response.pageNum = int.Parse(text2.text) - 1;
            }
        }
        else
        {
            _workPageData.response.pageNum = int.Parse(text.text);
        }

        ElectronicWorkInstance.GetInstance().DataRequestMessage(MessageCode.SET_CURR_WORKORDERPAGE, _workPageData.response.pageNum);
        Debug.Log(_workPageData.response.pageNum);

        WorkorderEventDefine.WorkorderJumpPage.SendEventMessage();
    }

    private void OnDestroy()
    {
        _eventGroup.RemoveAllListener();

        if(_pageNumButton != null)
        {
            _pageNumButton.Release();
            _pageNumButton = null;
        }
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值