上篇文章, 熟悉了ScrollView, 这次来看看ListView. 把稍复杂一点的控件熟悉一下, 再通过具体的项目学习框架. JSX的语法非常简洁, 写出同样的功能, 要清晰许多.
新建一个项目, 修改入口index.android.js
.
'use strict';
var React = require('react-native');
var {
AppRegistry,
} = React;
var ListViewModule = require('./list_view_module/index');
AppRegistry.registerComponent('RnListView', () => ListViewModule);
在list_view_module
文件夹中, 编写我们的Demo.
ListView
的基本样式就是flex: 1
, 需要定义行(row)样式(styles .button
), 图片样式(styles.image
)是圆角矩形.
'use strict'
var React = require('react-native');
var {
StyleSheet,
} = React;
var styles = StyleSheet.create({
button: {
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
margin: 10,
},
image: {
flex: 1,
height: 200,
borderRadius: 5,
borderWidth: 2,
borderColor: '#FF1492',
},
});
module.exports = styles;
逻辑非常简单: 连续显示图片, 每行可以点击, 提示图片内容.
'use strict'
var React = require('react-native');
var {
Text,
Image,
TouchableOpacity, // 按钮
ListView,
View,
ToastAndroid,
} = React;
var styles = require('./styles');
// 图片
var IMAGES = [
require('./images/total_girls.png'),
require('./images/jessicajung.png'),
require('./images/kimhyoyeon.png'),
require('./images/seohyun.png'),
require('./images/sooyoung.png'),
require('./images/sunny.png'),
require('./images/taeyeon.png'),
require('./images/tiffany.png'),
require('./images/yoona.png'),
require('./images/yuri.png'),
];
// 名字
var NAMES = [
'Girls\' Generation',
'Jessica Jung',
'Kim Hyo Yeon',
'Seo Hyun',
'Soo Young',
'Sunny',
'Taeyeon',
'Tiffany',
'Yoona',
'Yuri'
];
var ListViewModule = React.createClass({
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
return {
dataSource: ds.cloneWithRows(this._genRows())
};
},
_genRows: function() {
var re = [];
for (var i=0; i<IMAGES.length; ++i) {
re.push([ NAMES[i%NAMES.length], IMAGES[i%IMAGES.length] ]);
}
return re;
},
// 点击事件
_pressRow: function(rowToast: string) {
ToastAndroid.show(rowToast, ToastAndroid.SHORT);
},
_renderRow: function(rowData: array, sectionID: number, rowID: number) {
return (
<TouchableOpacity onPress={() => this._pressRow(rowData[0])}> <View> <View style={styles.button}> <Image style={styles.image} source={rowData[1]} /> </View> </View> </TouchableOpacity> ); }, render: function() { return( <ListView dataSource={this.state.dataSource} renderRow={this._renderRow} /> ); } }); module.exports = ListViewModule;
下面我们说说要点, ListView
的本质是从dataSource
中提取数组数据, 行数就是数组长度, 按照行(row)
赋予数组中的元素.
生成数据源: 判断更新状况, 把内容+图片
的数组添加到DataSource.
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); return { dataSource: ds.cloneWithRows(this._genRows()) }; }, _genRows: function() { var re = []; for (var i=0; i<IMAGES.length; ++i) { re.push([ NAMES[i%NAMES.length], IMAGES[i%IMAGES.length] ]); } return re; },
行视图, rowData
是行数据, rowID
是行号; 在点击时提示内容rowData[0]
, 显示图片资源rowData[1]
. _renderRow
负责创建行视图.
// 点击事件
_pressRow: function(rowToast: string) {
ToastAndroid.show(rowToast, ToastAndroid.SHORT);
},
_renderRow: function(rowData: array, sectionID: number, rowID: number) {
return (
<TouchableOpacity onPress={() => this._pressRow(rowData[0])}>
<View>
<View style={styles.button}>
<Image style={styles.image} source={rowData[1]} />
</View>
</View>
</TouchableOpacity>
);
},
使用ListView, 数据源(dataSource)
和行渲染(renderRow)
都已经创建, 赋值入ListView即可.
render: function() {
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
/>
);
}
Github下载地址
ListView
作为开发中常见的控件, 需要经常使用, 熟练掌握吧.
OK, Enjoy it!