Unity 中實現首尾無限循環的 ListView

之前已經實現過:

Unity 中實現可復用的 ListView-CSDN博客文章瀏覽閱讀5.6k次,點贊2次,收藏27次。源碼已放入我的 github,地址:Unity-ListView前言實現一個列表組件,表現方面最核心的部分就是重寫布局(Layout)。對于簡單的列表,尤其是“Cell數量固定且較少、沒有超頁滾動展示”一類的需求,使用UGUI自帶的布局組件進行布局即可。分別為:水平布局組件(Horizontal Layout Group)、豎直布局組件(Vertical Layout Gro..._unity listview https://blog.csdn.net/NRatel/article/details/100561203Unity 中實現可復用的 GridView-CSDN博客文章瀏覽閱讀4k次。本文介紹了如何基于Unity的UGUI系統設計一個靈活的GridView組件。作者分析了GridLayoutGroup的參數,討論了StartCorner和StartAxis的排布方式、Constraint的靈活性以及Padding與對齊方式的巧妙結合。在實現過程中,修改了ScrollRect的關聯ScrollBar和布局接口,設計了適應不同滑動方向的布局,并實現了元素復用邏輯,包括四種滑動方向的計算。此外,還探討了Content錨點、行列約束和對齊方式的調整,以提高組件的易用性。 https://blog.csdn.net/NRatel/article/details/124063559首尾無限循環 的列表,還是以?ListView 為基礎。

在此之前,先參照 GrideView 修改?ListView:

使其 繼承 UIScrollRect(原因是必須修改部分源碼)

并支持參數:

1、MovementAxis :
????????橫向滑動 或?豎向滑動。

2、StartSide :
????????橫向滑動時,可選 元素的排列方向:從左往右 或 從右往左;
????????豎向滑動時,可選 元素的排列方向:從上往下?或 從下往上。

3、ChildAligment :
????????橫向滑動時,可選 元素的上下對齊方式:居上/居中/居下;
? ? ? ? 豎向滑動時,可選 元素的左右對齊方式:居左/居中/居右。

----------------------------------------- NRatel割 -----------------------------------------

Loop 首尾循環的改動要點:
(以下僅以 MovementAxis=Horizontal,StartSide=Left 的情形闡述)

先看這種情況:核心內容寬度 > viewport 寬度

1、使 Content 在移動時,非原核心內容區也能夠顯示 0~Count-1 范圍內的 Cell元素,讓越界索引不要提前retrun,而是在顯示時轉到 0~Count-1 之中。

如圖:黑色區域為 Content, 當其繼續往右滑動時,進入Viewport、但已超出 Content 的部分,仍能生成越界元素,并能將越界索引轉到 界內索引之中。

需要修改?CalcIndexes,使其不要立刻攔截越界索引。而是在 DisAppearCells 和 AppearCells 時,根據 索引值判斷是否越界,抽出兩個方法:

//是否有效索引(只將顯示索引顯示到列表中,默認為 0~cellCount 之間)
//loop時,認為任意索引都是有效的,以使非 0~cellCount 的區域能夠顯示元素,之后再在 ConvertIndexToValid 轉換
protected virtual bool IsValidIndex(int index)
{if (m_Loop) { return true; }else { return index >= 0 && index < m_CellCount; }
}
//轉換索引至有效(默認無需處理)
//loop時,將任意索引數轉到 [0~cellCount-1] 中
protected virtual int ConvertIndexToValid(int index)
{if (m_Loop) { return (index % m_CellCount + m_CellCount) % m_CellCount; }else { return index; }
}

處理完本條之后,理論上,將 Content的寬度設為 無限大,就可以直接支持首尾無限循環。
不過,最好還是選擇位置重置的方案。

2、滑動時,從初始位置開始,只要向左/向右滑出超過1個重置單位,就將 Content 重置回起始位置。
(注意,滑動過程,完全無需考慮Cell顯示問題,完全由①處理,可將Content想象為一張整圖)
(注意這里說的 1個重置單位 = 1核心內容寬度 + 1個spacingX)

3、將 Content 寬度擴為原核心內容寬度擴展的N倍,使其滿足位置重置的基本條件。

????????支持從初始位置開始,向左向右各滑動1個重置單位,需要在兩側至少各擴展出1個重置單位。
????????但為了避免 翻超1個重置單位觸及邊緣 觸發回彈,可以額外多出1或2個重置單位。
? ? ? ? 注意,擴寬 Content 更多倍是毫無成本的!這里只是思考至少應該擴展幾倍。
????????所以,直接定為 2+2=4倍。

4、再回頭來思考 核心內容寬度 < viewport寬度 的倍數

????????在上面的基礎上,只需簡單處理:將 核心內容寬度 先翻倍,使超過 viewport寬度。
????????注意,這種情況下,在Viewport中會出現多個同一Cell,屬于正常現象。

5、重置Content位置。但小心不能影響到 ScrollRect 內部的 速度值計算!!!

? ? ? ? 我用了不少時間才解決這個問題。

? ? ? ? 位置的重置,不能放在?OnScrollValueChanged。原因是:

? ? ? ? ①、ScrollRect 的 LateUpdate中,有邏輯為:
????????開啟慣性速度選項,進行拖拽時,會根據Content相鄰兩幀的 位置確定后續的 慣性起始速度。

? ? ? ? 因此,如果在滑動過程中,如果只突然修改 Content 位置,將會導致 速度劇變

? ? ? ? ②、在?OnScrollValueChanged 修改?Content 位置過晚,將使 其他注冊?OnScrollValueChanged 的地方無法獲取的真實 value。

????????因此,可在?SetContentAnchoredPosition?方法中,增加一個虛方法,供子類重寫修改Content 的位置。

? ? ? ? 在具體修改Content位置時,還需注意:

? ? ? ? ①、要同時更新 m_PrevPosition,以使本幀 LateUpdate中 計算的 m_Velocity 不會因位置劇變而劇變。

? ? ? ? ②、要同時更新 m_ContentStartPosition,以使 OnDrag 中,Content位置跟隨鼠標移動時,不反復觸發此“位置超過一頁的重置邏輯”,否則下一幀 m_PrevPosition 又將執行一次偏移(上一行代碼),還是會導致速度劇變。

//Content初始位置
float contentStartPosX = -m_CellStartOffsetOnMovementAxis;
//獲取當前位置
float curContentPosX = m_Content.anchoredPosition.x;
//Content向左時,Content重置點坐標(初始位置左側1個重置寬度)
float leftResetPosX = contentStartPosX - m_LoopResetSizeOnMovementAxis;
//Content向右時,Content重置點坐標(初始位置右側1個重置寬度)
float rightResetPosX = contentStartPosX + m_LoopResetSizeOnMovementAxis;
if (curContentPosX < leftResetPosX)
{m_Content.anchoredPosition += Vector2.right * m_LoopResetSizeOnMovementAxis;//更新,以使本幀 LateUpdate中 計算的 m_Velocity 不會因位置劇變而劇變m_PrevPosition += Vector2.right * m_LoopResetSizeOnMovementAxis;//更新,以使 OnDrag 中,Content位置跟隨鼠標移動時,不反復觸發此“位置超過一頁的重置邏輯”,否則下一幀m_PrevPosition又將執行一次偏移(上一行代碼),還是會導致速度劇變m_ContentStartPosition += Vector2.right * m_LoopResetSizeOnMovementAxis;
}
else if (curContentPosX > rightResetPosX)
{m_Content.anchoredPosition += Vector2.left * m_LoopResetSizeOnMovementAxis;//更新,以使本幀 LateUpdate中 計算的 m_Velocity 不會因位置劇變而劇變m_PrevPosition += Vector2.left * m_LoopResetSizeOnMovementAxis;//更新,以使 OnDrag 中,Content位置跟隨鼠標移動時,不反復觸發此“位置超過一頁的重置邏輯”,否則下一幀m_PrevPosition又將執行一次偏移(上一行代碼),還是會導致速度劇變m_ContentStartPosition += Vector2.left * m_LoopResetSizeOnMovementAxis;
}

----------------------------------------- NRatel割 -----------------------------------------

實現效果:

源碼:

https://github.com/NRatel/Unity-ListViewhttps://github.com/NRatel/Unity-ListView

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85228.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85228.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85228.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【C++】 類和對象(上)

1.類的定義 1.1類的定義格式 ? class為定義類的關鍵字&#xff0c;后跟一個類的名字&#xff0c;{}中為類的主體&#xff0c;注意類定義結束時后?分號不能省 略。類體中內容稱為類的成員&#xff1a;類中的變量稱為類的屬性或成員變量;類中的函數稱為類的?法或 者成員函數。…

Transformer架構詳解:從Attention到ChatGPT

Transformer架構詳解&#xff1a;從Attention到ChatGPT 系統化學習人工智能網站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目錄 Transformer架構詳解&#xff1a;從Attention到ChatGPT摘要引言一、Attention機制&#xff1a;Transformer的…

Rock9.x(Linux)安裝Redis7

&#x1f49a;提醒&#xff1a;1&#xff09;注意權限問題 &#x1f49a; 查是否已經安裝了gcc gcc 是C語言編譯器&#xff0c;Redis是用C語言開發的&#xff0c;我們需要編譯它。 gcc --version如果沒有安裝gcc&#xff0c;那么我們手動安裝 安裝GCC sudo dnf -y install…

EasyExcel使用導出模版后設置 CellStyle失效問題解決

EasyExcel使用導出模版后在CellWriteHandler的afterCellDispose方法設置 CellStyle失效問題解決方法 問題描述&#xff1a;excel 模版塞入數據后&#xff0c;需要設置單元格的個性化設置時失效&#xff0c;本文以設置數據格式為例&#xff08;設置列的數據展示時需要加上千分位…

【Day41】

DAY 41 簡單CNN 知識回顧 數據增強卷積神經網絡定義的寫法batch歸一化&#xff1a;調整一個批次的分布&#xff0c;常用與圖像數據特征圖&#xff1a;只有卷積操作輸出的才叫特征圖調度器&#xff1a;直接修改基礎學習率 卷積操作常見流程如下&#xff1a; 1. 輸入 → 卷積層 →…

Express教程【002】:Express監聽GET和POST請求

文章目錄 2、監聽post和get請求2.1 監聽GET請求2.2 監聽POST請求 2、監聽post和get請求 創建02-app.js文件。 2.1 監聽GET請求 1??通過app.get()方法&#xff0c;可以監聽客戶端的GET請求&#xff0c;具體的語法格式如下&#xff1a; // 1、導入express const express req…

C# 文件 I/O 操作詳解:從基礎到高級應用

在軟件開發中&#xff0c;文件操作&#xff08;I/O&#xff09;是一項基本且重要的功能。無論是讀取配置文件、存儲用戶數據&#xff0c;還是處理日志文件&#xff0c;C# 都提供了豐富的 API 來高效地進行文件讀寫操作。本文將全面介紹 C# 中的文件 I/O 操作&#xff0c;涵蓋基…

Vue-Router簡版手寫實現

1. 路由庫工程設計 首先&#xff0c;我們需要創建幾個核心文件來組織我們的路由庫&#xff1a; src/router/index.tsRouterView.tsRouterLink.tsuseRouter.tsinjectionsymbols.tshistory.ts 2. injectionSymbols.ts 定義一些注入符號來在應用中共享狀態&#xff1a; import…

Electron-vite【實戰】MD 編輯器 -- 文件列表(含右鍵快捷菜單,重命名文件,刪除本地文件,打開本地目錄等)

最終效果 頁面 src/renderer/src/App.vue <div class"dirPanel"><div class"panelTitle">文件列表</div><div class"searchFileBox"><Icon class"searchFileInputIcon" icon"material-symbols-light:…

Remote Sensing投稿記錄(投稿郵箱寫錯、申請大修延期...)風雨波折投稿路

歷時近一個半月&#xff0c;我中啦&#xff01; RS是中科院二區&#xff0c;2023-2024影響因子4.2&#xff0c;五年影響因子4.9。 投稿前特意查了下預警&#xff0c;發現近五年都不在預警名單中&#xff0c;甚至最新中科院SCI分區&#xff08;2025年3月&#xff09;在各小類上…

吉林第三屆全國龍舟邀請賽(大安站)激情開賽

龍舟競渡處,瑞氣滿湖光。5月31日&#xff0c;金蛇獻瑞龍舞九州2025年全國龍舟大聯動-中國吉林第三屆全國龍舟邀請賽(大安站)“嫩江灣杯”白城市全民健身龍舟賽在吉林大安嫩江灣國家5A級旅游區玉龍湖拉開帷幕。 上午9時&#xff0c;伴隨著激昂的音樂&#xff0c;活力四射的青春舞…

華為OD機試真題——通過軟盤拷貝文件(2025A卷:200分)Java/python/JavaScript/C++/C語言/GO六種最佳實現

2025 A卷 200分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析; 并提供Java、python、JavaScript、C++、C語言、GO六種語言的最佳實現方式! 本文收錄于專欄:《2025華為OD真題目錄+全流程解析/備考攻略/經驗分享》 華為OD機試真題《通過…

一起學數據結構和算法(二)| 數組(線性結構)

數組&#xff08;Array&#xff09; 數組是最基礎的數據結構&#xff0c;在內存中連續存儲&#xff0c;支持隨機訪問。適用于需要頻繁按索引訪問元素的場景。 簡介 數組是一種線性結構&#xff0c;將相同類型的元素存儲在連續的內存空間中。每個元素通過其索引值&#xff08;數…

ZYNQ sdk lwip配置UDP組播收發數據

?? 一、顛覆認知:組播 vs 單播 vs 廣播 通信方式目標設備網絡負載典型應用場景單播1對1O(n)SSH遠程登錄廣播1對全網O(1)ARP地址解析組播1對N組O(1)視頻會議/物聯網群控創新價值:在智能工廠中,ZYNQ通過組播同時控制100臺AGV小車,比傳統單播方案降低92%網絡流量! ?? 二、…

機器學習:欠擬合、過擬合、正則化

本文目錄&#xff1a; 一、欠擬合二、過擬合三、擬合問題原因及解決辦法四、正則化&#xff1a;盡量減少高次冪特征的影響&#xff08;一&#xff09;L1正則化&#xff08;二&#xff09;L2正則化&#xff08;三&#xff09;L1正則化與L2正則化的對比 五、正好擬合代碼&#xf…

Linux命令之ausearch命令

一、命令簡介 ausearch 是 Linux 審計系統 (auditd) 中的一個實用工具,用于搜索審計日志中的事件。它是審計框架的重要組成部分,可以幫助系統管理員分析系統活動和安全事件。 二、使用示例 1、安裝ausearch命令 Ubuntu系統安裝ausearch命令,安裝后啟動服務。 root@testser…

mac電腦安裝nvm

方案一、常規安裝 下載安裝腳本&#xff1a;在終端中執行以下命令來下載并運行 NVM 的安裝腳本3&#xff1a; bash curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.39.5/install.sh | bash配置環境變量&#xff1a;安裝完成后&#xff0c;需要配置環境變量。如…

Excel 操作 轉圖片,轉pdf等

方式一 spire.xls.free&#xff08;沒找設置分辨率的方法&#xff09; macOs開發Java GUI程序提示缺少字體問題解決 Spire.XLS&#xff1a;一款Excel處理神器_spire.xls免費版和收費版的區別-CSDN博客 官方文檔 Spire.XLS for Java 中文教程 <dependency><groupI…

oracle goldengate實現遠程抽取postgresql 到 postgresql的實時同步【絕對無坑版,親測流程驗證】

oracle goldengate實現postgresql 到 postgresql的實時同步 源端&#xff1a;postgresql1 -> postgresql2 流復制主備同步 目標端&#xff1a;postgresql 數據庫版本&#xff1a;postgresql 12.14 ogg版本&#xff1a;21.3 架構圖&#xff1a; 數據庫安裝以及流復制主備…

2.從0開始搭建vue項目(node.js,vue3,Ts,ES6)

從“0到跑起來一個 Vue 項目”&#xff0c;重點是各個工具之間的關聯關系、職責邊界和技術演化脈絡。 從你寫代碼 → 到代碼能跑起來 → 再到代碼可以部署上線&#xff0c;每一步都有不同的工具參與。 &#x1f63a;&#x1f63a;1. 安裝 Node.js —— 萬事的根基 Node.js 是…