Unity笔记之下拉刷新列表

在这里插入图片描述
这样的效果;

代码:

using System;
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ScrollRectUpdateViewBase<T> : 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<GameObject, T> openDic = new Dictionary<GameObject, T>();
    private List<T> remainList = new List<T>();
    private List<T> allData = new List<T>();

    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<GameObject, T> createItemFinish;
    public Action<ScrollRectUpdateViewBase<T>> resetAction;

    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 = 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<T> list)
    {
        foreach (var openDicKey in this.openDic.Keys)
        {
            GameObject.Destroy(openDicKey);
        }

        allData = list;
        remainList = new List<T>(list);
        this.openDic = new Dictionary<GameObject, T>();
        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);
    }
}

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);
    }
}

场景:
在这里插入图片描述
在这里插入图片描述
就这些了。

哦对了,这个最好还是套一层,弄成泛型的,这样会好点

在这里插入图片描述
省事多了

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值