React Native_手把手教你做项目(二.视频列表页布局&Mock虚拟数据)
程序员文章站
2022-05-30 21:02:34
...
我们继续在上一篇文章的基础上编写我们的应用程序,视频列表页List
我们先写垃圾代码,把整个的架子搭起来,然后如果有其他页面通用的组件的话,我们再进行封装处理
ListView布局
list.js文件
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
ListView,
} from 'react-native';
export default class list extends Component{
constructor(props){
super(props);
this.state={
dataSource:new ListView.DataSource({
rowHasChanged:(r1,r2)=>r1!==r2,
})
}
}
componentDidMount() {
//加载数据
this.dsfetchData();
}
dsfetchData(){
this.setState({
dataSource:this.state.dataSource.cloneWithRows(['呵呵','哈哈','嘻嘻','嘿嘿','哎呦','不错哦'])
})
}
render() {
return (
<View style={styles.container}>
{/*导航条*/}
<View style={styles.header}>
<Text style={styles.headerText}>
视频列表
</Text>
</View>
{/*列表页面*/}
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
style={styles.listView}
/>
</View>
);
}
//下划线代表内部类自己用的函数,属于规范
_renderRow=(rowData)=>{
return (
<Text>{rowData}</Text>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
header:{
// marginTop:Platform.OS == 'ios'?20:0,
paddingTop:25,
paddingBottom:15,
backgroundColor:'#dddddd',
borderBottomWidth:0.5,
borderBottomColor:'black',
},
headerText:{
fontWeight:'600',
textAlign:'center',
fontSize: 16,
},
listView:{
}
});
Mock模拟数据
列表内容
Web应用前后端(台)分离:
后台向前台提供API接口,只负责数据的提供和计算,而完全不处理展现
前台通过Http(Ajax)请求获取数据, 在浏览器端动态构建界面显示数据设计JSON数据结构
- 利用Node+express提供模拟数据
优点:可以在浏览器端访问
缺点:如果是打包发布就无法访问模拟数据, 只能是测试时使用
RAP
RAP是一个可视化接口管理工具 通过分析接口结构,动态生成模拟数据,校验真实接口正确性, 围绕接口定义,通过一系列自动化工具提升我们的协作效率。我们的口号:提高效率,回家吃晚饭!
首先在RAP上面注册账号,添加团队,添加项目
注意这里的备注的@cparagraph(1, 3)
是在Mock中寻找的
完善模拟接口
设置完成后,点击
把生成的数据先复制到DataSource中,进行简单的页面布局
list.js
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
ListView,
TouchableOpacity,
Image
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import Dimensions from 'Dimensions';
const {width, height} = Dimensions.get('window');
export default class list extends Component{
constructor(props){
super(props);
this.state={
dataSource:new ListView.DataSource({
rowHasChanged:(r1,r2)=>r1!==r2,
})
}
}
componentDidMount() {
//加载数据
this.dsfetchData();
}
dsfetchData(){
this.setState({
dataSource:this.state.dataSource.cloneWithRows([ {
"_id":"630000201107028547","thumb":"http://dummyimage.com/1024x700/2026c9,图片上的文字)","title":"@cparagraph(1, 3)","video":"'http://v.youku.com/v_show/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0'"
}
,
{
"_id":"350000201510184550","thumb":"http://dummyimage.com/1024x700/e3bdd2,图片上的文字)","title":"@cparagraph(1, 3)","video":"'http://v.youku.com/v_show/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0'"
}
,
{
"_id":"130000199211104265","thumb":"http://dummyimage.com/1024x700/a242ec,图片上的文字)","title":"@cparagraph(1, 3)","video":"'http://v.youku.com/v_show/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0'"
}])
})
}
render() {
return (
<View style={styles.container}>
{/*导航条*/}
<View style={styles.header}>
<Text style={styles.headerText}>
视频列表
</Text>
</View>
{/*列表页面*/}
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
style={styles.listView}
/>
</View>
);
}
//下划线代表内部类自己用的函数,属于规范
_renderRow=(rowData)=>{
return (
<TouchableOpacity>
{/*整个Cell*/}
<View style={styles.cellStyle}>
{/*标题文字*/}
<Text style={styles.title}>{rowData.title}</Text>
<Image style={styles.thumb} source={{uri:rowData.thumb}} >
</Image>
<Icon name="ios-play"
size={30}
style={styles.play}
/>
{/*点赞&评论*/}
<View style={styles.cellFooter}>
{/*点赞*/}
<View style={styles.footerBox}>
<Icon name="ios-heart-outline"
size={30}
style={styles.boxIcon}
/>
{/*点赞文字*/}
<Text style={styles.boxText}>点赞</Text>
</View>
{/*评论*/}
<View style={styles.footerBox}>
<Icon name="ios-chatbubbles-outline"
size={30}
style={styles.boxIcon}
/>
{/*点赞文字*/}
<Text style={styles.boxText}>评论</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
header:{
// marginTop:Platform.OS == 'ios'?20:0,
paddingTop:25,
paddingBottom:15,
backgroundColor:'#dddddd',
borderBottomWidth:0.5,
borderBottomColor:'black',
},
headerText:{
fontWeight:'600',
textAlign:'center',
fontSize: 16,
},
listView:{
},
cellStyle:{
width:width,
marginTop:10,
backgroundColor:'white',
},
title:{
padding:10,
color:'black',
fontSize:18
},
thumb:{
width:width,
height:width*0.56,
resizeMode:'cover'
},
play:{
position:'absolute',
bottom:100,
right:14,
width:46,
height:46,
paddingTop:8,
paddingLeft:18,
backgroundColor:'transparent',
borderColor:'black',
borderWidth:0.5,
borderRadius:23,
},
cellFooter:{
flexDirection:'row',
justifyContent:'space-between',
backgroundColor:'#dddddd',
},
footerBox:{
padding:10,
flexDirection:'row',
backgroundColor:'white',
flex:1,
marginLeft:1,
justifyContent:'center',
},
boxIcon:{
fontSize:22,
color:'#333',
},
boxText:{
fontSize:18,
color:'#333',
paddingLeft:12,
marginTop:2
}
});
效果图:
请求mock数据
安装工具Mock.js
npm i mockjs –save
list.js
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
ListView,
TouchableOpacity,
Image
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import Dimensions from 'Dimensions';
const {width, height} = Dimensions.get('window');
// Mockjs 解析随机的文字
import Mock from 'mockjs';
export default class list extends Component{
constructor(props){
super(props);
this.state={
dataSource:new ListView.DataSource({
rowHasChanged:(r1,r2)=>r1!==r2,
}),
url:'http://rap.taobao.org/mockjs/35294/api/list?accessToken=001'
}
}
//即将显示
componentWillMount() {
//加载本地数据
// this.dsfetchData();
}
componentDidMount() {
//加载网络数据
this._fetchData();
}
_fetchData(){
fetch(this.state.url).then(
(response) => {
return response.json()
}
).then(
(response) => {
let result = Mock.mock(response);
console.log('服务器返回的数据是'+result);
//先判断有没有数据
if(result.success) {
this.setState({
dataSource:this.state.dataSource.cloneWithRows(result.data)
})
}
}
)
}
dsfetchData(){
let result = Mock.mock({
"data|20":
[
{
"_id":
"@ID",
"thumb":
"@IMG(1024x700,@COLOR(),\'\u56fe\u7247\u4e0a\u7684\u6587\u5b57\')",
"title":
"@cparagraph(1, 3)",
"video":
"\'http:\/\/v.youku.com\/v_show\/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0\'"
}
],
"success": true
})
this.setState({
dataSource:this.state.dataSource.cloneWithRows(result.data)
})
}
render() {
return (
<View style={styles.container}>
{/*导航条*/}
<View style={styles.header}>
<Text style={styles.headerText}>
视频列表
</Text>
</View>
{/*列表页面*/}
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
style={styles.listView}
/>
</View>
);
}
//下划线代表内部类自己用的函数,属于规范
_renderRow=(rowData)=>{
return (
<TouchableOpacity>
{/*整个Cell*/}
<View style={styles.cellStyle}>
{/*标题文字*/}
<Text style={styles.title}>{rowData.title}</Text>
<Image style={styles.thumb} source={{uri:rowData.thumb}} >
</Image>
<Icon name="ios-play"
size={30}
style={styles.play}
/>
{/*点赞&评论*/}
<View style={styles.cellFooter}>
{/*点赞*/}
<View style={styles.footerBox}>
<Icon name="ios-heart-outline"
size={30}
style={styles.boxIcon}
/>
{/*点赞文字*/}
<Text style={styles.boxText}>点赞</Text>
</View>
{/*评论*/}
<View style={styles.footerBox}>
<Icon name="ios-chatbubbles-outline"
size={30}
style={styles.boxIcon}
/>
{/*点赞文字*/}
<Text style={styles.boxText}>评论</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
header:{
// marginTop:Platform.OS == 'ios'?20:0,
paddingTop:25,
paddingBottom:15,
backgroundColor:'#dddddd',
borderBottomWidth:0.5,
borderBottomColor:'black',
},
headerText:{
fontWeight:'600',
textAlign:'center',
fontSize: 16,
},
listView:{
},
cellStyle:{
width:width,
marginTop:10,
backgroundColor:'white',
},
title:{
padding:10,
color:'black',
fontSize:18
},
thumb:{
width:width,
height:width*0.56,
resizeMode:'cover'
},
play:{
position:'absolute',
bottom:100,
right:14,
width:46,
height:46,
paddingTop:8,
paddingLeft:18,
backgroundColor:'transparent',
borderColor:'black',
borderWidth:0.5,
borderRadius:23,
},
cellFooter:{
flexDirection:'row',
justifyContent:'space-between',
backgroundColor:'#dddddd',
},
footerBox:{
padding:10,
flexDirection:'row',
backgroundColor:'white',
flex:1,
marginLeft:1,
justifyContent:'center',
},
boxIcon:{
fontSize:22,
color:'#333',
},
boxText:{
fontSize:18,
color:'#333',
paddingLeft:12,
marginTop:2
}
});
上一篇: RN拆包解析
下一篇: ReactNative-踩坑记2