这样的效果;
代码:
using System;
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ScrollRectUpdateView : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{
private ScrollRect scrollRect;
[SerializeField] private RectTransform contentTransform;
[SerializeField] private ScrollRefreshInfo upRefreshInfo;
[SerializeField] private ScrollRefreshInfo downRefreshInfo;
private bool isUpRefresh;
private bool isDownRefresh;
private bool isRefreshing;
[SerializeField] [ReadOnly] float refreshNumber = 100;
[SerializeField] [ReadOnly] float canRefreshNumber = 50;
private Action upAction;
private Action downAction;
private void Awake()
{
this.scrollRect = this.GetComponent<ScrollRect>();
if (scrollRect == null) throw new NullReferenceException();
upRefreshInfo.ShowAndHideSelf(false);
downRefreshInfo.ShowAndHideSelf(false);
this.isUpRefresh = false;
this.isDownRefresh = false;
isRefreshing = false;
}
public void OnBeginDrag(PointerEventData eventData)
{
if (this.isRefreshing) return;
}
public void OnDrag(PointerEventData eventData)
{
if (this.isRefreshing) return;
var rectTransform = this.transform.GetComponent<RectTransform>();
float height = 0f;
var childCount = this.contentTransform.childCount;
var child = this.contentTransform.GetChild(1).GetComponent<RectTransform>();
if (this.contentTransform.TryGetComponent(out VerticalLayoutGroup group))
{
height = child.rect.height * (childCount - 2) + group.spacing * (childCount - 3) - rectTransform.rect.height;
}
else
height = child.rect.height * (childCount - 2) - rectTransform.rect.height;
var he = this.contentTransform.anchoredPosition.y - height;
Debug.Log($"one : {he}, two : {height}");
// Up
if (this.contentTransform.anchoredPosition.y < 0)
{
this.upRefreshInfo.ShowAndHideSelf(true);
if (contentTransform.anchoredPosition.y - child.rect.height >= -this.canRefreshNumber)
{
this.upRefreshInfo.SetContent("下拉可刷新");
this.isUpRefresh = false;
}
else if (contentTransform.anchoredPosition.y - child.rect.height <= -this.refreshNumber)
{
this.upRefreshInfo.SetContent("释放后刷新");
this.isUpRefresh = true;
}
}
else
{
this.isUpRefresh = false;
this.upRefreshInfo.ShowAndHideSelf(false);
}
// down
if (he > 0)
{
this.downRefreshInfo.ShowAndHideSelf(true);
if (he <= this.canRefreshNumber)
{
this.downRefreshInfo.SetContent("上拉可刷新");
this.isDownRefresh = false;
}
else if (he >= this.refreshNumber)
{
this.downRefreshInfo.SetContent("释放后刷新");
this.isDownRefresh = true;
}
}
else
{
this.isDownRefresh = false;
this.downRefreshInfo.ShowAndHideSelf(false);
}
}
public void OnEndDrag(PointerEventData eventData)
{
if (this.isRefreshing) return;
if (this.isUpRefresh)
{
Debug.Log("开始刷新 Up");
StartCoroutine(RefreshData(this.upRefreshInfo));
}
else if (this.isDownRefresh)
{
Debug.Log("开始刷新 Down");
StartCoroutine(RefreshData(this.downRefreshInfo));
}
else
{
this.upRefreshInfo.ShowAndHideSelf(false);
this.downRefreshInfo.ShowAndHideSelf(false);
}
}
private IEnumerator RefreshData(ScrollRefreshInfo info)
{
isRefreshing = true;
info.SetContent("刷新中");
yield return new WaitForSeconds(3);
info.SetContent("刷新成功");
yield return new WaitForSeconds(2);
info.SetContent("释放后刷新");
info.ShowAndHideSelf(false);
this.isUpRefresh = false;
this.isDownRefresh = false;
isRefreshing = false;
}
}
ScrollRefreshInfo.cs
using TMPro;
using UnityEngine;
public class ScrollRefreshInfo : MonoBehaviour
{
private string oldStr;
[SerializeField] private GameObject imgRefresh;
[SerializeField] private TMP_Text txtContent;
public void SetContent(string str)
{
if (this.oldStr == str) return;
this.txtContent.text = str;
this.oldStr = str;
Debug.Log(str);
}
public void ShowAndHideSelf(bool isShow)
{
if (this.gameObject.activeSelf != isShow)
this.gameObject.SetActive(isShow);
}
}
场景:
就这些了。