ListView - 一個核心組件,用於高效地顯示一個能夠垂直滾動的變化的數據列表。最基本的使用方式就是建立一個ListView.DataSource數據源,而後給它傳遞一個普通的數據數組,再使用數據源來實例化一個ListView組件,而且定義它的renderRow回調函數,這個函數會接受數組中的每一個數據做爲參數,返回一個可渲染的組件(做爲listview的每一行)。react
ListView還支持一些高級特性,譬如給每段/組(section)數據添加一個帶有粘性的頭部(相似iPhone的通信錄,其首字母會在滑動過程當中吸附在屏幕上方);在列表頭部和尾部增長單獨的內容;在到達列表尾部的時候調用回調函數(onEndReached),還有在視野內可見的數據變化時調用回調函數(onChangeVisibleRows),以及一些性能方面的優化。ios
有一些性能優化使得ListView能夠滾動的更加平滑,尤爲是在動態加載可能很大(或者概念上無限長的)數據集的時候:git
只更新變化的行 - 提供給數據源的rowHasChanged函數能夠告訴ListView它是否須要重繪一行數據(即:數據是否發生了變化)參見ListViewDataSourcegithub
限制頻率的行渲染 - 默認狀況下,每次消息循環只有一行會被渲染(能夠用pageSize屬性配置)。這把較大的工做分散成小的碎片,以下降由於渲染而致使丟幀的可能性。react-native
一:屬性數組
1:ScrollView props... 性能優化
譯註:這意味着ListView能夠使用全部ScrollView的屬性。微信
2:dataSource ListViewDataSource app
3:ListView.DataSource實例(列表依賴的數據源)函數
4:initialListSize number
指定在組件剛掛載的時候渲染多少行數據。用這個屬性來確保首屏顯示合適數量的數據,而不是花費太多幀逐步顯示出來。
5:onChangeVisibleRows function
(visibleRows, changedRows) => void
當可見的行的集合變化的時候調用此回調函數。visibleRows 以 { sectionID: { rowID: true }}的格式包含了全部可見行,而changedRows 以{ sectionID: { rowID: true | false }}的格式包含了全部剛剛改變了可見性的行,其中若是值爲true表示一個行變得可見,而爲false表示行剛剛離開可視區域而變得不可見。
6:onEndReached function
當全部的數據都已經渲染過,而且列表被滾動到距離最底部不足onEndReachedThreshold個像素的距離時調用。原生的滾動事件會被做爲參數傳遞。譯註:當第一次渲染時,若是數據不足一屏(好比初始值是空的),這個事件也會被觸發。
7:onEndReachedThreshold number
調用onEndReached以前的臨界值,單位是像素。
8:pageSize number
每次事件循環(每幀)渲染的行數。
9:removeClippedSubviews bool
用於提高大列表的滾動性能。須要給行容器添加樣式overflow:'hidden'。(Android已默認添加此樣式)。此屬性默認開啓。
10:renderFooter function
() => renderable
頁頭與頁腳會在每次渲染過程當中都從新渲染(若是提供了這些屬性)。若是它們重繪的性能開銷很大,把他們包裝到一個StaticContainer或者其它恰當的結構中。頁腳會永遠在列表的最底部,而頁頭會在最頂部。
11:renderHeader function
renderRow function
(rowData, sectionID, rowID, highlightRow) => renderable
從數據源(Data source)中接受一條數據,以及它和它所在section的ID。返回一個可渲染的組件來爲這行數據進行渲染。默認狀況下參數中的數據就是放進數據源中的數據自己,不過也能夠提供一些轉換器。
若是某一行正在被高亮(經過調用highlightRow函數),ListView會獲得相應的通知。當一行被高亮時,其兩側的分割線會被隱藏。行的高亮狀態能夠經過調用highlightRow(null)來重置。
12:renderScrollComponent function
(props) => renderable
指定一個函數,在其中返回一個能夠滾動的組件。ListView將會在該組件內部進行渲染。默認狀況下會返回一個包含指定屬性的ScrollView。
13:renderSectionHeader function
(sectionData, sectionID) => renderable
若是提供了此函數,會爲每一個小節(section)渲染一個粘性的標題。
粘性是指當它剛出現時,會處在對應小節的內容頂部;繼續下滑當它到達屏幕頂端的時候,它會停留在屏幕頂端,一直到對應的位置被下一個小節的標題佔據爲止。
14:renderSeparator function
(sectionID, rowID, adjacentRowHighlighted) => renderable
若是提供了此屬性,一個可渲染的組件會被渲染在每一行下面,除了小節標題的前面的最後一行。在其上方的小節ID和行ID,以及鄰近的行是否被高亮會做爲參數傳遞進來。
15:scrollRenderAheadDistance number
當一個行接近屏幕範圍多少像素以內的時候,就開始渲染這一行。
16:iosstickyHeaderIndices [number]
一個子視圖下標的數組,用於決定哪些成員會在滾動以後固定在屏幕頂端。舉個例子,傳遞stickyHeaderIndices={[0]}會讓第一個成員固定在滾動視圖頂端。這個屬性不能和horizontal={true}一塊兒使用。
二:方法
1:getMetrics()
導出一些用於性能分析的數據。
2:scrollTo(...args)
滾動到指定的x, y偏移處,能夠指定是否加上過渡動畫。
參考 ScrollView#scrollTo.
三:實例代碼
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, TextInput, Alert, ListView } from 'react-native'; class ReactNativeProject extends Component { constructor(props) { super(props); var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.state = { dataSource: ds.cloneWithRows(['第一行內容', '第二行內容']), }; } render() { return ( <ListView style={styles.contentContainer} dataSource={this.state.dataSource} renderRow={(rowData) => <Text>{rowData}</Text>} /> ); } } const styles = StyleSheet.create({ contentContainer: { marginTop:64, backgroundColor:"#ff0000", } }); AppRegistry.registerComponent('ReactNativeProject', () => ReactNativeProject);
效果圖:
2:圖文行實例
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, TextInput, Alert, ListView, Image, TouchableOpacity, } from 'react-native'; var THUMB_URLS = [ {uri:"http://www.qq745.com/uploads/allimg/150408/1-15040PJ142-50.jpg"}, {uri:"http://ww2.sinaimg.cn/large/8989048bjw1dutawvaz66j.jpg"}, {uri:"http://img.lenovomm.com/s3/img/app/app-img-lestore/1993-2015-07-14062642-1436869602788.jpg?isCompress=true&width=342&height=513&quantity=0.8&rotate=true&dk=2"}, {uri:"http://c.hiphotos.baidu.com/exp/whcrop=160,120/sign=57e0ac939058d109c4b6fff0be28f18e/b8389b504fc2d5620f811f00e51190ef77c66c56.jpg"}, {uri:"http://f.hiphotos.baidu.com/exp/whcrop=160,120/sign=c3918fdeba014a90816b10ffc6070423/34fae6cd7b899e51d2350a7841a7d933c8950d26.jpg"}, {uri:"http://f.hiphotos.baidu.com/exp/whcrop=160,120/sign=2aba0e6674c6a7efb973fe64928a9260/902397dda144ad3494292c3ed2a20cf430ad85f1.jpg"}, {uri:"http://v1.qzone.cc/avatar/201503/04/17/44/54f6d3f8ae76c662.jpg%21200x200.jpg"}, {uri:"http://awb.img.xmtbang.com/img/uploadnew/201510/22/8d822cf398d1482fbe3d0ac6208050c4.jpg"}, {uri:"http://awb.img1.xmtbang.com/wechatmsg2015/article201506/20150601/thumb/6abcaf1a9c69496b8d51ec13eabfb5dd.jpg"}, {uri:"http://photo.jokeji.cn/uppic/15-06/27/17424334047046.jpg"}, {uri:"http://imgsrc.baidu.com/forum/w%3D580/sign=7eb05e9eddf9d72a17641015e428282a/3e87194c510fd9f9b3d66fc8212dd42a2a34a4c9.jpg"}, {uri:"http://img3.redocn.com/tupian/20120703/pazaimeinvdatuishangdeheibaichangmaochongwugou_664529_small.jpg"}, ]; class ReactNativeProject extends Component { constructor(props) { super(props); var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.state = { dataSource: ds.cloneWithRows(['row 1', 'row 2','row 3','row 4','row 5','row 6','row 7','row 8','row 9','row 10','row 11','row 12']), }; } _renderRow(rowData: string, sectionID: number, rowID: number) { var imgSource = THUMB_URLS[rowID]; return ( <TouchableOpacity> <View> <View style={styles.row}> <Image style={styles.thumb} source={imgSource} /> <Text style={{flex:1,fontSize:16,color:'blue'}}> {rowData + '我是測試行號哦~'} </Text> </View> </View> </TouchableOpacity> ); } render() { return ( <ListView dataSource={this.state.dataSource} renderRow={this._renderRow} /> ); } } const styles = StyleSheet.create({ row: { flexDirection: 'row', justifyContent: 'center', padding: 10, backgroundColor: '#F6F6F6', }, thumb: { width: 50, height: 50, }, }); AppRegistry.registerComponent('ReactNativeProject', () => ReactNativeProject);
效果圖:
最近有個妹子弄的一個關於擴大眼界跟內含的訂閱號,天天都會更新一些深度內容,在這裏若是你感興趣也能夠關注一下(嘿對美女跟知識感興趣),固然能夠關注後輸入:github 會有個人微信號,若是有問題你也能夠在那找到我;固然不感興趣無視此信息;