ScrollView 相關屬性樣式所有繼承react
dataSource ListViewDataSource 設置ListView的數據源git
initialListSize number
設置ListView組件剛剛加載的時候渲染的列表行數,用這個屬性肯定首屏或者首頁加載的數量,而不是花大量的時間渲染加載不少頁面數據,提升性能。github
onChangeVisibleRows function (visibleRows,changedRows)=>void。
當可見的行發生變化的時候回調該方法。json
onEndReachedThreshold number
當偏移量達到設置的臨界值調用onEndReachedreact-native
onEndReached function數組
當全部的數據項行被渲染以後,而且列表往下進行滾動。一直滾動到距離底部onEndReachedThredshold設置的值進行回調該方法。原生的滾動事件進行傳遞(經過參數的形式)。性能優化
pageSize number 每一次事件的循環渲染的行數數據結構
removeClippedSubviews booloop
該屬性用於提供大數據列表的滾動性能。該使用的時候須要給每一行(row)的佈局添加over:'hidden'樣式。該屬性默認是開啓狀態。佈局
renderFooter function 方法 ()=>renderable
在每次渲染過程當中頭和尾總會從新進行渲染。若是發現該從新繪製的性能開銷比較大的時候,可使用StaticContainer容器或者其餘合適的組件。
renderHeader function 方法
在每一次渲染過程當中Footer(尾)該會一直在列表的底部,header(頭)該會一直在列表的頭部,用法同上。
renderRow function (rowData,sectionID,rowID,highlightRow)=>renderable
該方法有四個參數,其中分別爲數據源中一條數據,分組的ID,行的ID,以及標記是不是高亮選中的狀態信息。
renderScrollComponent function
方法 (props)=>renderable 該方法能夠返回一個能夠滾動的組件。默認該會返回一個ScrollView
renderSectionHeader function (sectionData,sectionID)=>renderable
若是設置了該方法,這樣會爲每個section渲染一個粘性的header視圖。該視圖粘性的效果是當剛剛被渲染開始的時候,該會處於對應的內容的頂部,而後開始滑動的時候,該會跑到屏幕的頂端。直到滑動到下一個section的header(頭)視圖,而後被替代爲止。
renderSeparator function
(sectionID,rowID,adjacentRowHighlighted)=>renderable
若是設置該方法,會在被每一行的下面渲染一個組件做爲分隔。除了每個section分組的頭部視圖前面的最後一行。
scrollRenderAheadDistance number
進行設置當該行進入屏幕多少像素之內以後就開始渲染該行
ListView一樣支持一些高級特性,包括設置每一組的粘性的頭部(相似於iPhone)、支持設置列表的header以及footer視圖、當數據列表滑動到最底部的時候支持onEndReached方法回調、設備屏幕列表可見的視圖數據發生變化的時候回調onChangeVisibleRows以及一些性能方面的優化特性。
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, {Component} from 'react'; import { AppRegistry, StyleSheet, Text, View, Image, ListView, TouchableOpacity, AlertIOS, } from 'react-native'; var Dimensions = require('Dimensions'); var {width, height} = Dimensions.get('window'); // 引入數據文件 var models = require("./Wine.json"); var rn0910ListViewTest01 = React.createClass({ /** * 生命週期,不可更改的屬性在這裏 * @returns {{}} */ getDefaultProps() { return {} }, /** * 生命週期,狀態機在這裏 * @returns {{}} */ getInitialState() { // 建立數據源 rowHasChanged方法決定了ListView是否從新渲染當前這一行 var ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => { r1 !== r2 } }); return { // 數據源中的數據 dataSource: ds.cloneWithRows(models) } }, /** * 生命週期,複雜的操做在這裏 */ componentDidMount() { }, /** * 生命週期,渲染 * @returns {XML} */ render() { return ( <ListView dataSource={this.state.dataSource} // 指定數據源 renderRow={this.renderRow} // 渲染每一行 /> ); }, /** * ListView根據數據源的數據進行渲染 * @param rowData 每一項的數據 * @param sectionID 組號 * @param rowID 行號 * @param highlightRow * @returns {XML} */ renderRow(rowData, sectionID, rowID, highlightRow) { return ( <TouchableOpacity activeOpacity={0.7} onPress={() => this.cellDidClick(rowID, rowData)} > <View style={styles.wineCell}> <Image style={styles.icon} source={{uri: rowData.image}}/> <View style={styles.titleContainer}> <Text style={styles.title}>{rowData.name}</Text> <Text style={styles.subTitle}>${rowData.money}</Text> </View> </View> </TouchableOpacity> ); }, cellDidClick(rowID, rowData) { alert("點擊了" + rowID + rowData.name); } }); const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', paddingTop: 20 }, wineCell: { flexDirection: "row", borderBottomWidth: 1, borderBottomColor: '#eee', paddingLeft: 10, paddingTop: 10, paddingBottom: 10, backgroundColor: 'white' }, icon: { width: 60, height: 60, }, titleContainer: { flexDirection: "column", justifyContent: 'space-between' }, title: { fontSize: 15, fontWeight: 'bold', width: width - 60, paddingLeft: 10, paddingRight: 10 }, subTitle: { fontSize: 15, marginLeft: 10, } }); AppRegistry.registerComponent('rn0910ListViewTest01', () => rn0910ListViewTest01);
listViewContentStyle: { // ListView實現九宮格佈局,主要是這倆屬性 flexDirection: 'row', flexWrap: 'wrap' }, cellStyle: { alignItems: 'center', // 每一項設置寬高 width: cellWH, height: cellWH, marginLeft: hMargin, marginTop: tMargin },
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, {Component} from 'react'; import { AppRegistry, StyleSheet, Text, View, ListView, Image, TouchableOpacity, AlertIOS } from 'react-native'; // 引入json文件 var models = require("./shareData.json"); // 獲取屏幕寬度 var Dimensions = require('Dimensions'); var screen_Width = Dimensions.get('window').width; var col = 3; // 列數 var cellWH = 100; // 每項寬高 var tMargin = 25; // 行 頂間距 var hMargin = (screen_Width - cellWH * col) / (col + 1); // 每項之間的間距 var rn0912ListViewTest02 = React.createClass({ /** * 不可修改的屬性 * @returns {{}} */ getDefaultProps() { return {} }, /** * 狀態機 */ getInitialState() { var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); return { dataSource: ds.cloneWithRows(models.data) } }, /** * 渲染 * @returns {{}} */ render() { return ( <ListView dataSource={this.state.dataSource} renderRow={this.renderRow} contentContainerStyle={styles.listViewContentStyle} /> ) }, /** * 操做 */ componentDidMount() { }, renderRow(rowData) { return ( <TouchableOpacity activeOpacity={0.8} onPress={() => { alert("點擊分享到" + rowData.title) }} > <View style={styles.cellStyle}> <Image style={styles.iconStyle} source={{uri: rowData.icon}}/> <Text style={styles.nameStyle}>{rowData.title}</Text> </View> </TouchableOpacity> ); } }); const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, listViewContentStyle: { // ListView實現九宮格佈局,主要是這倆屬性 flexDirection: 'row', flexWrap: 'wrap' }, cellStyle: { alignItems: 'center', // 每一項設置寬高 width: cellWH, height: cellWH, marginLeft: hMargin, marginTop: tMargin }, iconStyle: { width: 80, height: 80, }, nameStyle: { fontSize: 14 } }); AppRegistry.registerComponent('rn0912ListViewTest02', () => rn0912ListViewTest02);
如何實現滾動時每一個sectionHeader會吸頂?
在ListView中要實現sticky,須要使用cloneWithRowsAndSections方法,將dataBlob(object),sectionIDs(array),rowIDs(array)三個值傳進去.
dataBlob包含ListView所需的全部的數據(sectionHeader 和 rows),在ListView渲染數據時,使用getSectionData 和 getRowData 來渲染每一行數據. dataBlob的 key 值包含sectionID + rowID
sectionIDs 用語表示每組section
rowIDs 用於描述每一個section裏的每行數據的位置及是否須要渲染. 在ListView渲染時,會先遍歷 rowIDs 獲取到對應的 dataBlob 數據
getInitialState() { var getSectionHeaderData = (dataBlob, sectionID) => { return dataBlob[sectionID]; } var getRowData = (dataBlob, sectionID, rowID) => { return dataBlob[sectionID + ":" + rowID]; } return { // 設置數據源,數據龐大,在 dataSource: new ListView.DataSource({ getSectionHeaderData: getSectionHeaderData, // 獲取組數據 getRowData: getRowData, // 獲取行數據 rowHasChanged: (r1, r2) => { r1 !== r2 }, // 何時建立行 sectionHeaderHasChanged: (s1, s2) => { s1 !== s2 } // 何時建立組 }) }; },
this.setState({ dataSource: this.state.dataSource.cloneWithRowsAndSections(dataBlob, sectionIDs, rowIDs) });
<ListView dataSource={this.state.dataSource} renderRow={this.renderRow} renderSectionHeader={this.renderSectionHeader} />
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, {Component} from 'react'; import { AppRegistry, StyleSheet, Text, View, ListView, Image, TouchableOpacity } from 'react-native'; var carData = require("./Car.json"); var rn0913ListViewTest03 = React.createClass({ /** * 不可更改的屬性 * @returns {{}} */ getDefaultProps() { return {}; }, /** * 狀態機 * @returns {{}} */ getInitialState() { var getSectionHeaderData = (dataBlob, sectionID) => { return dataBlob[sectionID]; } var getRowData = (dataBlob, sectionID, rowID) => { return dataBlob[sectionID + ":" + rowID]; } return { // 這裏就沒有指定數據源,因爲須要處理數據,因此在componentDidMount()方法中進行數據處理 dataSource: new ListView.DataSource({ getSectionHeaderData: getSectionHeaderData, // 獲取組數據 getRowData: getRowData, // 獲取行數據 rowHasChanged: (r1, r2) => { r1 !== r2 }, // 何時建立行 sectionHeaderHasChanged: (s1, s2) => { s1 !== s2 } // 何時建立組 }) }; }, /** * 渲染界面 */ render() { return ( <View style={styles.container}> <View style={styles.nav}> <Text style={styles.navTitle}>Chaos車庫</Text> </View> <ListView dataSource={this.state.dataSource} renderRow={this.renderRow} renderSectionHeader={this.renderSectionHeader} /> </View> ); }, /** * 渲染每一項 * @param rowData * @returns {XML} */ renderRow(rowData) { return ( <TouchableOpacity activeOpacity={0.8}> <View style={styles.cellStyle}> <Image style={styles.imgStyle} source={{uri: rowData.icon}}/> <Text style={styles.carTitleStyle}>{rowData.name}</Text> </View> </TouchableOpacity> ); }, /** * 渲染每一組 * @param sectionData * @returns {XML} */ renderSectionHeader(sectionData) { return ( <TouchableOpacity activeOpacity={0.8}> <View style={styles.headerStyle}> <Text style={styles.headerTextStyle}>{sectionData}</Text> </View> </TouchableOpacity> ); }, /** * 複雜操做 */ componentDidMount() { this.loadDataFromJson(); }, /** * 加載數據,處理數據 */ loadDataFromJson() { var jsonData = carData.data; var dataBlob = {}, // 對象 sectionIDs = [], rowIDs = [], // 這是個二維數組 cars = []; for (var i = 0; i < jsonData.length; i++) { // 肯定每組的id sectionIDs.push(i); // 肯定每組的id對應的組數據 dataBlob[i] = jsonData[i].title; // 獲取行集合 cars = jsonData[i].cars; rowIDs[i] = []; // 二維數組,每一項都是行id的數組 for (var j = 0; j < cars.length; j++) { rowIDs[i].push(j); // 肯定每一行的數據 dataBlob[i + ":" + j] = cars[j]; } } // 給ListView的數據源賦值 this.setState({ dataSource: this.state.dataSource.cloneWithRowsAndSections(dataBlob, sectionIDs, rowIDs) }); } }); const styles = StyleSheet.create({ container: {}, nav: { height: 64, backgroundColor: '#eee', alignItems: 'center', justifyContent: 'center' }, navTitle: { fontSize:26 }, headerStyle: { backgroundColor: '#ccc', height:30, }, headerTextStyle: { lineHeight:30, paddingLeft:10 }, cellStyle: { borderBottomColor:'#eee', borderBottomWidth:0.5, flexDirection:'row', alignItems:'center', padding:10 }, imgStyle: { width: 60, height: 60 }, carTitleStyle: { marginLeft:10 } }); AppRegistry.registerComponent('rn0913ListViewTest03', () => rn0913ListViewTest03);