React Native常用組件之ListView

學習iOS開發(fā)的同學應該都知道UITableView,幾乎每個APP中都有它的存在,而且衍生出各種形態(tài);那么同樣,ListView就是在React Native中的tableView,而且更加簡單和靈活易用;讓我們一起搞定它。

一、前言

ListView組件是React Native中一個比較核心的組件,用途非常的廣; 該組件設計用來高效的展示垂直滾動的數(shù)據(jù)列表:
1.1 首先創(chuàng)建一個ListView.DataSource數(shù)據(jù)源,然后給它傳遞一個普通的數(shù)據(jù)數(shù)組;
1.2 使用數(shù)據(jù)源(data source)實例化一個ListView組件,定義一個renderRow回調(diào)函數(shù),這個函數(shù)會接受數(shù)組中的每個數(shù)據(jù)作為參數(shù),并返回一個可渲染的組件(該就是列表的每一行的item)。

圖片 1.png

二、ListView常用的屬性

ScrollView 相關(guān)屬性樣式全部繼承

dataSource   ListViewDataSource  設置ListView的數(shù)據(jù)源

initialListSize  number  
設置ListView組件剛剛加載的時候渲染的列表行數(shù),用這個屬性確定首屏或者首頁加載的數(shù)量,而不是花大量的時間渲染加載很多頁面數(shù)據(jù),提高性能。

onChangeVisibleRows  function (visibleRows,changedRows)=>void。
當可見的行發(fā)生變化的時候回調(diào)該方法。

onEndReachedThreshold  number 
當偏移量達到設置的臨界值調(diào)用onEndReached

onEndReached function 
當所有的數(shù)據(jù)項行被渲染之后,并且列表往下進行滾動。一直滾動到距離底部onEndReachedThredshold設置的值進行回調(diào)該方法。原生的滾動事件進行傳遞(通過參數(shù)的形式)。

pageSize   number 每一次事件的循環(huán)渲染的行數(shù)

 removeClippedSubviews  bool  
  該屬性用于提供大數(shù)據(jù)列表的滾動性能。該使用的時候需要給每一行(row)的布局添加over:'hidden'樣式。該屬性默認是開啟狀態(tài)。

renderFooter function 方法  ()=>renderable 
       在每次渲染過程中頭和尾總會重新進行渲染。如果發(fā)現(xiàn)該重新繪制的性能開銷比較大的時候,可以使用StaticContainer容器或者其他合適的組件。

renderHeader  function 方法 
      在每一次渲染過程中Footer(尾)該會一直在列表的底部,header(頭)該會一直在列表的頭部,用法同上。

 renderRow function  (rowData,sectionID,rowID,highlightRow)=>renderable   
     該方法有四個參數(shù),其中分別為數(shù)據(jù)源中一條數(shù)據(jù),分組的ID,行的ID,以及標記是否是高亮選中的狀態(tài)信息。

renderScrollComponent function 
方法 (props)=>renderable  該方法可以返回一個可以滾動的組件。默認該會返回一個ScrollView

renderSectionHeader function (sectionData,sectionID)=>renderable  
如果設置了該方法,這樣會為每一個section渲染一個粘性的header視圖。該視圖粘性的效果是當剛剛被渲染開始的時候,該會處于對應的內(nèi)容的頂部,然后開始滑動的時候,該會跑到屏幕的頂端。直到滑動到下一個section的header(頭)視圖,然后被替代為止。

renderSeparator function (sectionID,rowID,adjacentRowHighlighted)=>renderable 
如果設置該方法,會在被每一行的下面渲染一個組件作為分隔。除了每一個section分組的頭部視圖前面的最后一行。

scrollRenderAheadDistance number  
進行設置當該行進入屏幕多少像素以內(nèi)之后就開始渲染該行

三、ListView的高階特性

ListView同樣支持一些高級特性,包括設置每一組的粘性的頭部(類似于iPhone)、支持設置列表的header以及footer視圖、當數(shù)據(jù)列表滑動到最底部的時候支持onEndReached方法回調(diào)、設備屏幕列表可見的視圖數(shù)據(jù)發(fā)生變化的時候回調(diào)onChangeVisibleRows以及一些性能方面的優(yōu)化特性。
ListView設計的時候,當需要動態(tài)加載非常大的數(shù)據(jù)的時候,下面有一些方法性能優(yōu)化的方法可以讓我們的ListView滾動的時候更加平滑:
(1)只更新渲染數(shù)據(jù)變化的那一行 ,rowHasChanged方法會告訴ListView組件是否需要重新渲染當前那一行。
(2)選擇渲染的頻率,默認情況下面每一個event-loop(事件循環(huán))只會渲染一行(可以同pageSize自定義屬性設置)。這樣可以把大的工作量進行分隔,提供整體渲染的性能。

四、綜合大演練

4.1 最簡單的ListView
核心代碼:

圖片 2.png

運行效果截圖:

圖片 3.png

4.2 帶有組頭的汽車品牌展示
核心代碼:


圖片 4.png
圖片 5.png
圖片 6.png
圖片 7.png

運行結(jié)果:

圖片 8.png

項目技術(shù)點分析:
在React Native中,ScrollView組件可以使用 stickyHeaderIndices 輕松實現(xiàn) sticky 效果;而使用ListView組件時,使用 stickyHeaderIndices 則不生效。
如何實現(xiàn)滾動時每個section header會吸頂?
在ListView中要實現(xiàn) sticky ,需要使用 cloneWithRowsAndSections 方法,將 dataBlob(object), sectionIDs (array), rowIDs (array) 三個值傳進去。
dataBlob
dataBlob 包含ListView所需的所有數(shù)據(jù)(section header 和 rows),在ListView渲染數(shù)據(jù)時,使用getSectionData 和 getRowData 來渲染每一行數(shù)據(jù)。 dataBlob 的 key 值包含 sectionID + rowId

圖片 9.png

sectionIDs
sectionIDs 用于標識每組section。

圖片 10.png

rowIDs
rowIDs 用于描述每個 section 里的每行數(shù)據(jù)的位置及是否需要渲染。在ListView渲染時,會先遍歷 rowIDs 獲取到對應的 dataBlob 數(shù)據(jù)。

圖片 11.png

模擬對應的數(shù)據(jù)結(jié)構(gòu)

圖片 12.png

在 DataSource 中,設置ListView獲取row和section的方法

圖片 13.png

最后

  1. 刷新狀態(tài),將數(shù)據(jù)傳入到listView中:
this.setState({
    dataSource:this.state.dataSource.cloneWithRowsAndSections(dataBlob, sectionIDs, rowIDs)
});
  1. 設置listView的相關(guān)屬性:
<ListView
    dataSource = {this.state.dataSource}
    renderRow = {this.renderRow}
    renderSectionHeader = {this.renderSectionHeader}
    />

4.3 用ListView實現(xiàn)九宮格布局
相關(guān)技術(shù)點:
通常情況下,我們對ListView的操作是縱向的,如果是橫向的,則需要設置ListView的contentContainerStyle屬性,添加flexDirection:‘row’讓多個ListView在同一行顯示,而且通過flexWrap:'wrap'進行換行。

核心代碼:

圖片 14.png
圖片 15.png
圖片 16.png

運行效果:

圖片 17.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容