(1) ListView:一个核心组件,用于高效地显示一个可以垂直滚动的变化的数据列表。
基本语法:
- dataSource :代表ListView的数据源
- renderRow :代表渲染的每一行
(1) dataSource
- new ListView.DataSource
- rowHasChanged
- cloneWithRows
(1) 如果我们要创建一个数据源,最基本的方法就是创建一个ListView.DataSource数据源,然后通过cloneWithRows方法为其传递一个数组。
(2) 其中提供给数据源的rowHasChanged函数可以告诉ListView它是否需要重绘一行数据,即数据是否发生了改变,即在需要重绘界面的时候会进行判断,如果之前页面中的改行数据没有发生变化,则不再进行重绘,否则进行重绘。(即比对前后同一条数据是否发生了改变)
(1-1) dataSource初始化:
-
constructor(props) {
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(['row 1', 'row 2']),
};
}
(1-2) dataSource初始化时,可以定义一个函数在制定数据源。比如下面的:
-
dataSource: ds.cloneWithRows(this._genRows())的_genRows函数;
-
constructor(props){
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(this._genRows()),
};
}
_genRows(){
const dataBlob = [];
for(let i = 0 ; i< 200 ; i ++ ){
dataBlob.push("aa"+i);
}
return dataBlob;
}
(3) dataSource的使用:
-
通过dataSource={ this.state.dataSource }来调用
-
<ListView
dataSource={this.state.dataSource}
renderRow={ this._renderRow.bind(this) }
/>
(2) renderRow
(1) 该属性需要传入一个方法,该方法如上所示,他会从数据源中接受一条数据,以及他和他所在的section的Id,返回一个可渲染的组件来为这行数据进行渲染,默认情况下参数中的数据就是放进数据源中的数据本身,不过也可以提供一些转换器。
(2) 如果某一行正在被高亮(通过调用highlightRow函数),ListView会得到相应的通知。当一行被高亮时,其两侧的分割线会被隐藏。行的高亮状态可以通过调用highlightRow(null)来重置。
_renderRow(rowData, sectionID, rowID){
return (
<View>
<Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
</View>
);
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow} //注意这里没有括号( (不是this._renderRow) )
/>
);
},
完整代码:
export default class List extends Component {
constructor(props) {
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(this._genRows()),
};
}
_genRows() {
const data = [];
for(var i=0; i<100; i++){
data.push("aa" + i);
}
return data;
};
_pressRow(rowID){
alert("这是第"+ rowID + "行");
};
_renderRow(rowData, sectionID, rowID) {
return (
<TouchableOpacity onPress={()=>this._pressRow(rowID)}>
<View>
<Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
<Text style={{backgroundColor:'green'}}>{ rowData}</Text>
</View>
</TouchableOpacity>
);
}
render() {
return (
<View style={styles.content}>
<View style={ styles.header}>
<Text style={styles.headerTitle}>
列表页
</Text>
</View>
<ListView
dataSource={this.state.dataSource}
renderRow={ this._renderRow.bind(this) }
/>
</View>
)
}
}
(3)ListView的点击事件:
TouchableOpacity或者TouchableHighlight
- 当我们需要给ListView的每一行添加点击事件时,只需要在其外层包裹一层TouchableOpacity或者TouchableHighlight,定义好onPress方法即可。
- 需要注意的是,在ListView的renderRow属性中调用_renderRow一定要绑定this,否则onPress中的this就会指向错误
_pressRow(rowID){
alert("hellow"+rowID);
}
_renderRow(rowData, sectionID, rowID){
return (
<TouchableOpacity onPress={()=>this._pressRow(rowID)}>
<View>
<Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
<Item_MyListView info={rowData}></Item_MyListView>
</View>
</TouchableOpacity>
);
}
<ListView dataSource={this.state.dataSource}
renderRow={this._renderRow.bind(this)}
/>
(4) Dimensions接口 (dimensions是规格尺寸的意思)
- (1)引入Dimensions模块api
- (2)var width = Dimensions.get('window').width;
- (2)var height = Dimensions.get('window').height;
- (3)使用: width : width;
完整代码:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
View,
Text,
Image,
ListView,
TouchableOpacity,
Dimensions
}from 'react-native';
var width = Dimensions.get('window').width;
// var height = Dimensions.get('window').height;
export default class List extends Component {
constructor(props) {
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([ {
"id": "710000201512201032",
"thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
"video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
},
{
"id": "540000201705130953",
"thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
"video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
},
{
"id": "36000020090726779X",
"thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
"video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
},
{
"id": "23000019890819858X",
"thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
"video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
},
{
"id": "810000199101084138",
"thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
"video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
},
{
"id": "810000198412233773",
"thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
"video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
},
{
"id": "610000200610314331",
"thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
"video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
},
{
"id": "360000201607162472",
"thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
"video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
}
]),
};
}
_renderRow(rowData, sectionID, rowID) {
return (
<TouchableOpacity>
<View>
<View style={ styles.titleContainer}>
<Text style={styles.title}>美女和男神的养成密集,让赵丽颖来告诉你</Text>
</View>
<View>
<Image source={{ uri: rowData.thumb }} style={styles.img}></Image>
<Image source={ require('../../go.png') } style={styles.go}></Image>
</View>
<View style={styles.bottom}>
<View style={styles.bottomBoth}>
<Image style={styles.sLogo} source={ require('../../love.png') }></Image>
<Text style={ styles.bottomText}>喜欢</Text>
</View>
<View style={styles.bottomBoth}>
<Image style={styles.sLogo2} source={ require('../../discuss.png') }></Image>
<Text style={ styles.bottomText}>评论</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
}
render() {
return (
<View style={styles.content}>
<View style={ styles.header}>
<Text style={styles.headerTitle}>
列表页
</Text>
</View>
<ListView
dataSource={this.state.dataSource}
renderRow={ this._renderRow }
/>
</View>
)
}
}
const styles = StyleSheet.create({
content: {
flex:1,
// justifyContent: 'center',
// alignItems: 'center'
},
header: {
backgroundColor: '#ee735c',
paddingTop:16,
paddingBottom:16
},
headerTitle: {
color:'white',
fontWeight: '600',
textAlign: 'center',
fontSize: 18,
letterSpacing: 300,
},
img: {
width: width,
height: 300
},
go: {
position: 'absolute',
width: 50,
height: 50,
bottom: 30,
right:60
},
title: {
fontSize: 20,
letterSpacing: 18
},
titleContainer: {
height:46,
marginTop:14
},
bottom: {
height:60,
paddingBottom:84,
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor:"#eee"
},
bottomBoth: {
flexDirection: 'row',
justifyContent: 'center',
width: width / 2 - 0.5,
backgroundColor:"white",
height:70,
paddingTop: 4,
alignItems: 'center'
},
sLogo: {
width: 38,
height:38,
marginRight: 8
},
sLogo2: {
width: 42,
height:44,
marginRight: 8
},
bottomText: {
fontSize: 20
}
});
(5) onEndReached:上滑预加载
(6) onEndReachedThreshold:离底部多高时进行预加载;(threshold:临界值的意思)
<ListView
dataSource= { this.state.dataSource }
renderRow = { this._renderRow }
onEndReached = { this._fetchMoreData}
onEndReachedThreshold = { 20 }
/>
网友评论