Unity3d UGUI插件之TSTableView


  TSTableView是Tacticsoft工作室開發的一款適用於UGUI的列表(Table)插件,設計靈感來源於iOS/Mac的UITableView,提供高復用、高性能的列表,其主要特點是:

  采用MVC模式

  良好的性能和內存占用優化

  復用列表項

  遺憾的是它暫時不支持橫向列表,需要開發者自己擴展,還有就是優化無止境。

 

         首先介紹下TSTableView的使用方法。

 

         上圖是TSTableView編輯時的層次結構。TableViewContainer節點掛載Mask(UGUI)組件,同ScrollView(UGUI)一樣用於列表顯示區域的裁剪。TableView節點掛載了TableView組件和ScrollRect(UGUI)組件。TableViewContent節點掛載了VerticalLayoutGroup組件,用於列表項的縱向布局。

 

         TSTableView設計上采用MVC模式,View功能由TableView提供,控制顯示和處理用戶輸入;實現ITableViewDataSource接口的類實現Model功能,提供列表數據;自定義一個Controller組件來控制視圖和通知狀態改變,為TableView設置數據源,需要將它掛載到具體對象上。

 

         其中ITableViewDataSource定義如下,它為TableView提供列表項數量、列表項高度、創建列表項接口:

         public interface ITableViewDataSource

         {

                   // get the number of rows that a certain table should display

                   int GetNumberOfRowsForTableView(TableView tableView);

                   // get the height of a row of a certain cell in the table view

                   float GetHeightForRowInTableView(TableView tableView, int row);

                   // create a cell for a certain row in a table view,

// callers should use tableView.GetReusableCell to cache objects.

                   TableViewCell GetCellForRowInTableView(TableView tableView, int row);

         }

         除此之外,需要提供列表項預制件,它設計了具體的列表顯示,需要掛載TableViewCell子類組件和LayoutElement組件,以便TableView能夠識別和調用相關接口。

         以下是TSTableView運行時的層次結構:

 

         TableViewContent節點下存放所有正在使用的列表項,其中TopContentPlaceHolder和BottomContentHolder提供占位功能,緩存的列表項放在隱藏的ReusableCell節點下。

 

         接下來重點討論TableView的設計原理。

         TableView維護一個可見列表項字典和一個緩存列表項字典,可見列表項使用字典(Dictionary)相比列表(List)會占用更多內存空間,但查找、刪除效率更高,其實可以考慮使用鏈表(LinkedList)可能更好一些。緩存列表因為需要支持不同列表項的混排,采用按標識字符串做key的字典,value使用鏈表來串起同類列表項。

         private Dictionary<int, TableViewCell> m_visibleCells;

         private Dictionary<string, LinkedList<TableViewCell>> m_reusableCells;

 

         TableView層次結構上非常巧妙地設計兩個占位項來動態計算和伸縮占位空間,分別是TopContentPlaceHolder和BottomContentPlaceHolder,它們掛載LayoutElement組件,能夠動態改變占位空間。

 

 

     假定當前使用的是一個超長列表。初始狀態下,不需要TopContentPlaceHolder占位隱藏即可,除了視口可見的幾個列表項,其余列表項因為不可見無需在列表中存在,而內容空間空間都由BottomContentPlaceHolder來完成,此時無緩存項。上面是層次結構和布局示意圖。

 

         隨着列表滑動到中間位置,TopContentPlaceHolder和BottomContentPlaceHolder同時可見,它們分別代表視口之上的不可見空間和視口之下的不可見空間。視口中可顯示的列表項數目不預知,因為每個列表項的高度可變,列表項可以是不同類型,所以列表在不同滑動位置,緩存字典中的緩存項數目會動態變化。上面是層次結構和布局示意圖。

 

         當列表項滑動到底部時,底部不需要占位項BottomContentPlaceHolder,頂部占位項TopContentPlaceHolder則會占取視口之外的內容空間。上面是層次結構和布局示意圖。

 

         為了維持可見列表和計算當前上下占位空間的大小,TableView維護了兩個數組。一個是各列表項高度值數組(包含留白),會隨着列表初始化、刪除和添加列表項、列表重建,相對應地重建和修改高度值數組。另一個是各列表項累積高度值數組,記錄各列表項距頂部的高度值,可以用來快速計算並獲取當前視口中可見的列表項。同時使用一個已累積索引變量來記錄已計算累積高度值的索引,這樣可以在需要的時候才去完成累積值計算,得到惰性計算的目的。

         public float[] m_rowHeights;

         private float[] m_cumulativeRowHeights;

         private int m_cleanCumulativeIndex;

 

         TSTableView是一個針對超長列表的小巧插件,其設計上巧妙地利用現有UGUI組件來達到高復用、高性能的列表效果,可以為我們自定義控件提供一些設計上的方法。

 

  附上:

    開源網址: https://bitbucket.org/tacticsoft/tstableview


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM