本来想写点ListView的东西, 但是在发现ScrollView实现列表(list)时, 有很多需要注意的地方, 就写了一个小Demo简要说明一下. 功能非常简单, 在滑动ScrollView中, 设置多个图片, 每个图片可以点击, 弹出图片信息.
效果1. 配置
从一个HelloWorld工程开始, 搭建项目.
入口index.android.js
, 跳转模块RnListView
.
'use strict';
var React = require('react-native');
var {
AppRegistry,
} = React;
var RnListView = require('./list_view_module/index');
AppRegistry.registerComponent('RnListView', () => RnListView);
2. 主工程
含有资源信息, 卡片视图, 批量创建方式, 主视图.
'use strict'
var React = require('react-native');
var {
Text,
View,
Image,
ScrollView,
TouchableOpacity,
ToastAndroid,
} = React
// 样式
var styles = require('./style');
// 图片
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'
];
// Card视图
var Card = React.createClass({
showToast: function(num: i) {
ToastAndroid.show(NAMES[num].toString(), ToastAndroid.SHORT);
},
render: function() {
return (
<TouchableOpacity
style={styles.button}
onPress={() => this.showToast(this.props.num)}
>
<View style={styles.blank}/>
<Image
style={styles.image}
resizeMode={'cover'}
source={this.props.img}/>
<View style={styles.blank}/>
</TouchableOpacity>
);
}
});
// 批量创建
var createCardRow = (img, i) => <Card key={i} img={img} num={i}/>;
var ListViewModule = React.createClass({
render: function() {
var verticalScrollView = (
<ScrollView
style={styles.container}>
{IMAGES.map(createCardRow)}
</ScrollView>
);
return verticalScrollView;
}
});
module.exports = ListViewModule;
3. 卡片视图
最外层是触摸感应控件(TouchableOpacity
), 触摸会改变透明度, 包含样式和Toast显示, 内部视图是左右留白
, 和中部卡片区域
. 属性是num
模块位置, img
视图资源.
// Card视图
var Card = React.createClass({
showToast: function(num: i) {
ToastAndroid.show(NAMES[num].toString(), ToastAndroid.SHORT);
},
render: function() {
return (
<TouchableOpacity
style={styles.button}
onPress={() => this.showToast(this.props.num)}
>
<View style={styles.blank}/>
<Image
style={styles.image}
resizeMode={'cover'}
source={this.props.img}/>
<View style={styles.blank}/>
</TouchableOpacity>
);
}
});
点击事件
onPress
, 使用回调方式()=>
, 否则直接触发.
通过设置空白View实现, 左右留空, 中间匹配(match).
批量设置, 把资源数组IMAGES
, 映射(map)成字典数组(img, pos)
, 设置Card的key和其他属性.
var createCardRow = (img, i) => <Card key={i} img={img} num={i}/>;
在循环视图中, 每个独立视图, 都需要单独设置唯一key, 定制单独接口. 参考
key
属性不能直接使用, 需要具体id时, 额外传入.
主模块, 使用图片资源创建多个视图.
var ListViewModule = React.createClass({
render: function() {
var verticalScrollView = (
<ScrollView
style={styles.container}>
{IMAGES.map(createCardRow)}
</ScrollView>
);
return verticalScrollView;
}
});
4. 样式
滚动控件, 每一行, 行内三个控件.
'use strict'
var React = require('react-native');
var {
StyleSheet,
} = React;
var styles = StyleSheet.create({
container: {
flex: 1,
},
button: {
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
margin: 10,
},
image: {
flex: 1,
height: 200,
borderRadius: 5,
borderWidth: 2,
borderColor: '#FF1492',
},
blank: {
width: 10,
}
});
module.exports = styles;
动画
container
是ScrollView的布局, 设置flex属性1
;
button
是每行布局, 包含左右空白和中间视图, 间距10;
image
是图片布局, 只设置高, 宽度通过flex自动匹配;
blank
是空白布局, 宽度占位10.
JavaScript是一门非常清晰的语言, flex样式也很优雅, 配合ReactNative有着不一样的体验. ReactNative可能会改变移动开发的格局. 现在已经日渐成熟, 还要看下一步的发展.
Github下载地址
OK, Enjoy it!
网友评论