Application scenarios
For backpack interfaces, leaderboard lists, chat messages, and other interfaces with a large number of UI lists, the conventional practice is to generate a grid for each piece of data. When the amount of data is larger, more and more Gameobjects will be generated, causing Caton.
This article is about how to solve the UI list stuck. Only a specified number of Gameobjects are generated in the list, and data is updated when sliding to ensure performance.
LoopScrollRect (infinite sliding without jamming)
Plugin address: https://github.com/qiankanglai/LoopScrollRect
Chinese document: http://qiankanglai.me/2015/08/15/LoopScrollRect/
Applicable to UGUI, supports UGUI's native GridLayout, ScrollBar
My modified version: https://github.com/zhaoqingqing/LoopScrollRect.git
Principle analysis
Modifications based on UGUI's ScrollRect
The differences between the two are //==========LoopScrollRect==========
identified by using the source code comparison:
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
Example of use
You can refer to the demo example
If used in lua, the logic is the same as C#, the steps are as follows:
1. Register events, unregister
2. Update the list according to the data in the refresh function
3. Calling logic
Registration issue
Register the list sliding event and register it once in OnInit to refresh the list
This event is triggered in C#, the callback is registered in Lua, and the event has two parameters
self.chatScrollRect.dataSource:ScrollToTextEvent("+", handler(self, UIChat.OnScrollChat, self, cellTrans, idx))
unregister
Unregistered list swipe event, canceled in OnClose
self.chatScrollRect.dataSource:ScrollToTextEvent("-", UIChat.OnScrollChat)
Trigger swipe event (refresh each item)
The event is fired when:
- If all the values of the list have been generated, it will not trigger during the sliding process, otherwise it will trigger
- Fires when RefreshCells or RefillCellsFromEnd is called
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
Manually refresh the list
--设置列表的总数,并刷新cell
self.scrollRect.itemTypeStart = 0 ---让列表从头开始滑动
self.chatScrollRect.totalCount = 10
self.chatScrollRect:RefreshCells()
Refresh and let the list slide to the bottom
self.chatScrollRect:RefillCellsFromEnd()
The difference between the two refresh functions
RefreshCells: List refresh
RefillCellsFromEnd: Refresh from the bottom message and slide to the bottom
List of events that slide to the bottom
Like UGUI's ScrollRect, add a scrollbar to scrollRect and capture the OnEndDrag event. The example is as follows:
self.chatScrollRect.onEndDrag = function(data)
if self.chatScrollbar.value >= 1 then
print("scroll to bottom")
end
end
If your data volume is particularly large, perform paging request data when sliding to the bottom event
If you are doing paging: It is recommended to set the data once when sliding to a certain order of magnitude and sliding to the bottom to ensure the smoothness of the sliding
prefabSource is nil
If the prefabSource is reported as nil in the hot update package, it is because the prefabSource will be lost after the hot update of the dll, and the prefabSource needs to be reassigned in lua, for example:
self.scrollRect.prefabSource = CS.UnityEngine.UI.XLoopScrollPrefabSource(self.itemCell.gameObject)
Tips and Matters
Cell refers to: each grid, or each list
Bind the LayoutElement component for each Cell, check Preferred Width and Preferred Height, and assign appropriate values to them to ensure that the list is adaptive.
Jump to the specified index/Item: https://github.com/qiankanglai/LoopScrollRect/issues/14
Do not bind the initInStart script and call RefillCells(90)
查找某一项的取巧做法:可以用id做为Cell的名字,当在查找时,根据FindChild(id)找到这一项,进行刷新。