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);