using System; using System.Collections; using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class ScrollRectUpdateViewBase : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler { private ScrollRect scrollRect; [SerializeField] private RectTransform contentTransform; [SerializeField] private ScrollRefreshInfo upRefreshInfo; [SerializeField] private ScrollRefreshInfo downRefreshInfo; [SerializeField] private GameObject item; [SerializeField] private int onceRefreshCount = 10; private Dictionary openDic = new Dictionary(); private List remainList = new List(); private List allData = new List(); private bool isUpRefresh; private bool isDownRefresh; private bool isRefreshing; [SerializeField] [ReadOnly] float refreshNumber = 100; [SerializeField] [ReadOnly] float canRefreshNumber = 50; [SerializeField] [ReadOnly] float canShowRefreshNumber = 20; private Action upAction; private Action downAction; public Action createItemFinish; public Action> resetAction; private void Awake() { this.scrollRect = this.GetComponent(); 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(); float height = 0f; var childCount = this.contentTransform.childCount; var child = this.contentTransform.GetChild(1).GetComponent(); 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 = 0f; if (this.allData.Count > this.onceRefreshCount) he = this.contentTransform.anchoredPosition.y - height; // Up if (this.contentTransform.anchoredPosition.y < -0.5f && this.contentTransform.anchoredPosition.y < -canShowRefreshNumber) { this.upRefreshInfo.ShowAndHideSelf(true); if (contentTransform.anchoredPosition.y >= -this.canRefreshNumber) { this.upRefreshInfo.SetContent("下拉可刷新"); this.isUpRefresh = false; } else if (contentTransform.anchoredPosition.y <= -this.refreshNumber) { this.upRefreshInfo.SetContent("释放后刷新"); this.isUpRefresh = true; } } else { this.isUpRefresh = false; this.upRefreshInfo.ShowAndHideSelf(false); } // down if (he > 0.5f && he > canShowRefreshNumber) { 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(RefreshUpData()); } else if (this.isDownRefresh) { Debug.Log("开始刷新 Down"); StartCoroutine(RefreshDownData()); } else { this.upRefreshInfo.ShowAndHideSelf(false); this.downRefreshInfo.ShowAndHideSelf(false); } } private IEnumerator RefreshUpData() { isRefreshing = true; this.upRefreshInfo.SetContent("Up刷新中"); yield return new WaitForSeconds(2); this.upRefreshInfo.SetContent("Up刷新成功"); yield return new WaitForSeconds(1); this.upRefreshInfo.SetContent("Up释放后刷新"); // CheckIsNeedTran(); this.upRefreshInfo.ShowAndHideSelf(false); this.isUpRefresh = false; this.isDownRefresh = false; isRefreshing = false; } private IEnumerator RefreshDownData() { isRefreshing = true; this.downRefreshInfo.SetContent("Down刷新中"); yield return new WaitForSeconds(1); var result = this.RefreshData(); if (result) this.downRefreshInfo.SetContent("Down刷新成功"); else this.downRefreshInfo.SetContent("没有更多数据了"); yield return new WaitForSeconds(1); this.downRefreshInfo.SetContent("Down释放后刷新"); this.downRefreshInfo.ShowAndHideSelf(false); this.isUpRefresh = false; this.isDownRefresh = false; isRefreshing = false; } void CheckIsNeedTran() { var tmp1 = this.downRefreshInfo.transform; int siblingIndex = tmp1.GetSiblingIndex(); var count = (this.contentTransform.childCount) - siblingIndex; if (count <= 0) return; for (var i = 1; i < count; i++) { int ii = i + siblingIndex; var child = this.contentTransform.GetChild(ii); var index = child.GetSiblingIndex(); int index1 = tmp1.GetSiblingIndex(); child.SetSiblingIndex(index1); tmp1.SetSiblingIndex(index); } } public void RefreshInitData(List list) { foreach (var openDicKey in this.openDic.Keys) { GameObject.Destroy(openDicKey); } allData = list; remainList = new List(list); this.openDic = new Dictionary(); this.RefreshData(); } private bool RefreshData() { int tmp = this.onceRefreshCount; if (remainList.Count < 10) { tmp = remainList.Count; } if (this.remainList.Count == 0) { Debug.Log("已经全部刷新了"); return false; } for (int i = 0; i < tmp; i++) { var o = GameObject.Instantiate(this.item, this.item.transform.parent); var remain = this.remainList[0]; o.SetActive(true); this.openDic.Add(o, remain); createItemFinish?.Invoke(o, remain); this.remainList.RemoveAt(0); } CheckIsNeedTran(); return true; } // TODO: 充值好恶心啊啊啊啊啊啊啊啊啊啊啊 public void ResetData() { foreach (var openDicKey in this.openDic.Keys) { GameObject.Destroy(openDicKey); } resetAction?.Invoke(this); } }