228 lines
7.3 KiB
C#
228 lines
7.3 KiB
C#
|
|
/****************************************************************************
|
|||
|
|
* Copyright (c) 2018.8 liangxie
|
|||
|
|
*
|
|||
|
|
* http://qframework.io
|
|||
|
|
* https://github.com/liangxiegame/QFramework
|
|||
|
|
*
|
|||
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|||
|
|
* in the Software without restriction, including without limitation the rights
|
|||
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|||
|
|
* furnished to do so, subject to the following conditions:
|
|||
|
|
*
|
|||
|
|
* The above copyright notice and this permission notice shall be included in
|
|||
|
|
* all copies or substantial portions of the Software.
|
|||
|
|
*
|
|||
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
|
|
* THE SOFTWARE.
|
|||
|
|
****************************************************************************/
|
|||
|
|
|
|||
|
|
using UnityEngine;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using UnityEngine.EventSystems;
|
|||
|
|
using UnityEngine.UI;
|
|||
|
|
using UnityEngine.Events;
|
|||
|
|
|
|||
|
|
namespace QFramework
|
|||
|
|
{
|
|||
|
|
public class UIScrollPageChangeEvent : UnityEvent<int, int> {}
|
|||
|
|
|
|||
|
|
public class UIScrollPage : MonoBehaviour, IBeginDragHandler, IEndDragHandler
|
|||
|
|
{
|
|||
|
|
ScrollRect rect;
|
|||
|
|
|
|||
|
|
//页面:0,1,2,3 索引从0开始
|
|||
|
|
//每页占的比列:0/3=0 1/3=0.333 2/3=0.6666 3/3=1
|
|||
|
|
//float[] pages = { 0f, 0.333f, 0.6666f, 1f };
|
|||
|
|
List<float> pages = new List<float>();
|
|||
|
|
|
|||
|
|
int currentPageIndex = -1;
|
|||
|
|
|
|||
|
|
//滑动速度
|
|||
|
|
public float smooting = 4;
|
|||
|
|
|
|||
|
|
//滑动的起始坐标
|
|||
|
|
float targethorizontal = 0;
|
|||
|
|
|
|||
|
|
//是否拖拽结束
|
|||
|
|
bool isDrag = false;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 用于返回一个页码,-1说明page的数据为0
|
|||
|
|
/// </summary>
|
|||
|
|
private UIScrollPageChangeEvent mOnPageChanged;
|
|||
|
|
|
|||
|
|
float startime = 0f;
|
|||
|
|
float delay = 0.1f;
|
|||
|
|
|
|||
|
|
void Awake()
|
|||
|
|
{
|
|||
|
|
rect = transform.GetComponent<ScrollRect>();
|
|||
|
|
startime = Time.time;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void Update()
|
|||
|
|
{
|
|||
|
|
if (Time.time < startime + delay) return;
|
|||
|
|
UpdatePages();
|
|||
|
|
//如果不判断。当在拖拽的时候要也会执行插值,所以会出现闪烁的效果
|
|||
|
|
//这里只要在拖动结束的时候。在进行插值
|
|||
|
|
if (!isDrag && pages.Count > 0)
|
|||
|
|
{
|
|||
|
|
rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, targethorizontal, Time.deltaTime * smooting);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void OnBeginDrag(PointerEventData eventData)
|
|||
|
|
{
|
|||
|
|
isDrag = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void OnEndDrag(PointerEventData eventData)
|
|||
|
|
{
|
|||
|
|
isDrag = false;
|
|||
|
|
|
|||
|
|
if (eventData != null)
|
|||
|
|
{
|
|||
|
|
bool bLeft = eventData.position.x < eventData.pressPosition.x;
|
|||
|
|
if (bLeft)
|
|||
|
|
{
|
|||
|
|
if (currentPageIndex < pages.Count - 1)
|
|||
|
|
currentPageIndex++;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (currentPageIndex > 0)
|
|||
|
|
currentPageIndex--;
|
|||
|
|
}
|
|||
|
|
mOnPageChanged.Invoke(pages.Count, currentPageIndex);
|
|||
|
|
targethorizontal = pages[currentPageIndex];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//float posX = rect.horizontalNormalizedPosition;
|
|||
|
|
//int index = 0;
|
|||
|
|
////假设离第一位最近
|
|||
|
|
//float offset = Mathf.Abs(pages[index] - posX);
|
|||
|
|
//for (int i = 1; i < pages.Count; i++)
|
|||
|
|
//{
|
|||
|
|
// float temp = Mathf.Abs(pages[i] - posX);
|
|||
|
|
// if (temp < offset)
|
|||
|
|
// {
|
|||
|
|
// index = i;
|
|||
|
|
// //保存当前的偏移量
|
|||
|
|
// //如果到最后一页。反翻页。所以要保存该值,如果不保存。你试试效果就知道
|
|||
|
|
// offset = temp;
|
|||
|
|
// }
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
//if(index!=currentPageIndex)
|
|||
|
|
//{
|
|||
|
|
// currentPageIndex = index;
|
|||
|
|
// OnPageChanged(pages.Count, currentPageIndex);
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
///*
|
|||
|
|
// 因为这样效果不好。没有滑动效果。比较死板。所以改为插值
|
|||
|
|
// */
|
|||
|
|
////rect.horizontalNormalizedPosition = page[index];
|
|||
|
|
|
|||
|
|
|
|||
|
|
//targethorizontal = pages[index];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void UpdatePages()
|
|||
|
|
{
|
|||
|
|
// 获取子对象的数量
|
|||
|
|
int count = this.rect.content.childCount;
|
|||
|
|
int temp = 0;
|
|||
|
|
for (int i = 0; i < count; i++)
|
|||
|
|
{
|
|||
|
|
if (this.rect.content.GetChild(i).gameObject.activeSelf)
|
|||
|
|
{
|
|||
|
|
temp++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
count = temp;
|
|||
|
|
|
|||
|
|
if (pages.Count != count)
|
|||
|
|
{
|
|||
|
|
if (count != 0)
|
|||
|
|
{
|
|||
|
|
pages.Clear();
|
|||
|
|
for (int i = 0; i < count; i++)
|
|||
|
|
{
|
|||
|
|
float page = 0;
|
|||
|
|
if (count != 1)
|
|||
|
|
page = i / ((float) (count - 1));
|
|||
|
|
pages.Add(page);
|
|||
|
|
//Debug.Log(i.ToString() + " page:" + page.ToString());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
OnEndDrag(null);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// force set page index
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="pageIndex"></param>
|
|||
|
|
public void SetPage(int pageIndex)
|
|||
|
|
{
|
|||
|
|
isDrag = false;
|
|||
|
|
UpdatePages();
|
|||
|
|
|
|||
|
|
currentPageIndex = Mathf.Clamp(pageIndex, 0, pages.Count - 1);
|
|||
|
|
mOnPageChanged.Invoke(pages.Count, currentPageIndex);
|
|||
|
|
targethorizontal = pages[currentPageIndex];
|
|||
|
|
rect.horizontalNormalizedPosition = targethorizontal;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// get all pages' count
|
|||
|
|
/// </summary>
|
|||
|
|
public int GetPageCount()
|
|||
|
|
{
|
|||
|
|
return pages.Count;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// get current showed page index
|
|||
|
|
/// </summary>
|
|||
|
|
public int GetCurrentPageIndex()
|
|||
|
|
{
|
|||
|
|
return currentPageIndex;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// register page change event listener
|
|||
|
|
/// </summary>
|
|||
|
|
public void AddPageChangeListener(UnityAction<int, int> listener)
|
|||
|
|
{
|
|||
|
|
if (mOnPageChanged == null)
|
|||
|
|
mOnPageChanged = new UIScrollPageChangeEvent();
|
|||
|
|
mOnPageChanged.AddListener(listener);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// remove page change event listener
|
|||
|
|
/// </summary>
|
|||
|
|
public void RemovePageChangeListener(UnityAction<int, int> listener)
|
|||
|
|
{
|
|||
|
|
if (mOnPageChanged == null)
|
|||
|
|
return;
|
|||
|
|
mOnPageChanged.RemoveListener(listener);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void OnDestroy()
|
|||
|
|
{
|
|||
|
|
if (mOnPageChanged != null)
|
|||
|
|
mOnPageChanged.RemoveAllListeners();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|