1. 程式人生 > >[UI列表]LoopScrollRect無限滑動不卡頓

[UI列表]LoopScrollRect無限滑動不卡頓

分享圖片 close 對比 部分 ets init ace fresh reward

應用場景

對於背包界面,排行榜列表,聊天消息,等有大量的UI列表的界面,常規做法是為每一條數據生成一個格子,在數據量越大的情況下,會生成越來越多的Gameobject,引起卡頓。

這篇文章講述的就是解決UI列表卡頓的方法,在列表中只生成指定數量的Gameobject,滑動時進行數據更新,保證性能。

技術分享圖片

LoopScrollRect(無限滑動不卡頓)

插件地址:https://github.com/qiankanglai/LoopScrollRect

中文文檔:http://qiankanglai.me/2015/08/15/LoopScrollRect/

適用於UGUI,支持UGUI原生的GridLayout,ScrollBar

原理分析

在UGUI的ScrollRect基礎上作的修改

兩者的差異部分使用//==========LoopScrollRect==========標識出來了,源代碼對比:

UGUI的ScrollRect:https://bitbucket.org/Unity-Technologies/ui/src/5.2/UnityEngine.UI/UI/Core/ScrollRect.cs?fileviewer=file-view-default

LoopScrollRect:https://github.com/qiankanglai/LoopScrollRect/blob/master/Assets/Scripts/LoopScrollRect.cs

使用示例

可以參考demo的示例

如果在lua中使用,邏輯和C#的一樣,步驟如下:

1.註冊事件、取消註冊

2.在刷新函數根據數據更新列表

3.調用邏輯

註冊事件

註冊列表滑動事件,在OnInit中註冊一次,用來刷新列表

此事件在C#中觸發,Lua中註冊回調,事件有兩個參數

  self.chatScrollRect.dataSource:ScrollToTextEvent("+", handler(self, UIChat.OnScrollChat, self, cellTrans, idx))

取消註冊

取消註冊的列表滑動事件,在OnClose中取消

  self.chatScrollRect.
dataSource:ScrollToTextEvent("-", UIChat.OnScrollChat)

觸發滑動事件(刷新每一項)

在以下情況事件會被觸發:

  1. 如果列表的值已全部生成出來,在滑動過程中不會觸發,否則會觸發
  2. 調用RefreshCells或RefillCellsFromEnd時,會觸發
function UIRewardResources:OnScrollEvent(cellTrans, idx)
    if (not cellTrans or not idx) then
        return
    end
    idx = idx + 1 -- Lua的索引從1開始,而scrollRect是從0開始
    local data = DataCenter.resource.data[idx]
    --執行你的刷新邏輯
    self:DoRenderItem(cellTrans, data)
end

手動刷新列表

--設置列表的總數,並刷新cell
self.chatScrollRect.totalCount = 10
self.chatScrollRect:RefreshCells()

刷新並讓列表滑動到底部

self.chatScrollRect:RefillCellsFromEnd()

兩個刷新函數區別

RefreshCells:列表刷新

RefillCellsFromEnd:從最底部的消息開始刷新,並滑動到底部

列表滑動到底部的事件

和UGUI的ScrollRect的做法一樣,為scrollRect添加一個scrollbar,捕捉OnEndDrag事件,示例如下:

    self.chatScrollRect.onEndDrag = function(data)
        if self.chatScrollbar.value >= 1 then
            print("scroll to bottom")
        end
    end

如果你的數據量特別大,在滑動到底部事件時進行分頁請求數據

如果是做分頁:建議在滑動到某個數量級且滑動到底部時,設置一次數據,保證滑動的流暢性

prefabSource為nil

如果在熱更新的包中報prefabSource為nil,是因為熱更新dll之後,prefabSource會丟失,需要在lua對prefabSource重新賦值,示例:

self.scrollRect.prefabSource = CS.UnityEngine.UI.XLoopScrollPrefabSource(self.itemCell.gameObject)

技巧和事項

Cell指:每一個格子,或每一項列表

為每一個Cell都綁定LayoutElement組件,並勾選Preferred Width 和Preferred Height,且給它們賦合適值,保證列表自適應。

跳轉到指定的index/Item:https://github.com/qiankanglai/LoopScrollRect/issues/14

查找某一項的取巧做法:可以用id做為Cell的名字,當在查找時,根據FindChild(id)找到這一項,進行刷新。

[UI列表]LoopScrollRect無限滑動不卡頓