本文案例、代码及主要内容基于知乎前端专栏翻译的文章《深入浅出React Native:使用JavaScript构建原生应用》《Introducing React Native: Building Apps with JavaScript》而写。
在原文的基础上做了一些校对,并增加了android得环境安装和调试的内容。
由我书写的注释将会显示左边这个紫色竖线(#523f6d),而原文的注释为蓝色的(#559bce)。
内容传送门
一、《深入浅出R跟我学用React Native构建原生应用(一)
二、《深入浅出R跟我学用React Native构建原生应用(二)
三、《深入浅出R跟我学用React Native构建原生应用(三)
四、《深入浅出R跟我学用React Native构建原生应用(四)
五、《深入浅出R跟我学用React Native构建原生应用(五)
六、《深入浅出R跟我学用React Native构建原生应用(六)
可点击样式
这些 React Native 的原生代码现在应该理解起来轻车熟路了,所以本教程将会加快速度。
在 SearchResults.js 中,destructuring 声明后面添加以下语句来定义样式:
var styles = StyleSheet.create({
thumb: {
width: 80,
height: 80,
marginRight: 10
},
textContainer: {
flex: 1
},
separator: {
height: 1,
backgroundColor: '#dddddd'
},
price: {
fontSize: 25,
fontWeight: 'bold',
color: '#48BBEC'
},
title: {
fontSize: 20,
color: '#656565'
},
rowContainer: {
flexDirection: 'row',
padding: 10
}
});
这些定义了每一行的样式。
接下来修改 renderRow() 如下:
renderRow(rowData, sectionID, rowID) {
var price = rowData.price_formatted.split(' ')[0];
return (
<TouchableHighlight onPress={() => this.rowPressed(rowData.guid)}
underlayColor='#dddddd'>
<View>
<View style={styles.rowContainer}>
<Image style={styles.thumb} source={{ uri: rowData.img_url }} />
<View style={styles.textContainer}>
<Text style={styles.price}>£{price}</Text>
<Text style={styles.title}
numberOfLines={1}>{rowData.title}</Text>
</View>
</View>
<View style={styles.separator}/>
</View>
</TouchableHighlight>
);
}
这个操作修改了返回的价格,将已经格式了化的”300000 GBP”中的GBP后缀删除。然后它通过你已经很熟悉的技术来渲染每一行的 UI 。这一次,通过一个 URL 来提供缩略图的数据, React Native 负责在主线程之外解码这些数据。
同时要注意 TouchableHighlight 组件中 onPress属性后使用的箭头函数;它用于捕获每一行的 guid。
最后一步,给类添加一个方法来处理按下操作:
rowPressed(propertyGuid) {
var property = this.props.listings.filter(prop => prop.guid === propertyGuid)[0];
}
该方法通过用户触发的属性来定位。目前该方法没有做任何事,你可以稍后处理。现在,是时候欣赏你的大作了。
回到模拟器,按下 Cmd + R 查看结果:
看起来好多了——尽管你会怀疑是否任何人都能承受住在伦敦的代价!
是时候向应用程序添加最后一个视图了。
房产详情视图
添加一个新的文件 PropertyView.js 到项目中,在文件的顶部添加如下代码:
'use strict';
var React = require('react-native');
var {
StyleSheet,
Image,
View,
Text,
Component
} = React;
信手拈来了吧!
接着添加如下样式:
var styles = StyleSheet.create({
container: {
marginTop: 65
},
heading: {
backgroundColor: '#F8F8F8',
},
separator: {
height: 1,
backgroundColor: '#DDDDDD'
},
image: {
width: 400,
height: 300
},
price: {
fontSize: 25,
fontWeight: 'bold',
margin: 5,
color: '#48BBEC'
},
title: {
fontSize: 20,
margin: 5,
color: '#656565'
},
description: {
fontSize: 18,
margin: 5,
color: '#656565'
}
});
然后加上组件本身:
class PropertyView extends Component {
render() {
var property = this.props.property;
var stats = property.bedroom_number + ' bed ' + property.property_type;
if (property.bathroom_number) {
stats += ', ' + property.bathroom_number + ' ' + (property.bathroom_number > 1
? 'bathrooms' : 'bathroom');
}
var price = property.price_formatted.split(' ')[0];
return (
<View style={styles.container}>
<Image style={styles.image}
source={{uri: property.img_url}} />
<View style={styles.heading}>
<Text style={styles.price}>£{price}</Text>
<Text style={styles.title}>{property.title}</Text>
<View style={styles.separator}/>
</View>
<Text style={styles.description}>{stats}</Text>
<Text style={styles.description}>{property.summary}</Text>
</View>
);
}
}
render() 前面部分对数据进行了处理,与通常的情况一样,API 返回的数据良莠不齐,往往有些字段是缺失的。这段代码通过一些简单的逻辑,让数据更加地规整一些。
render 剩余的部分就非常直接了。它就是一个简单的这个状态不可变状态的函数。
最后在文件的末尾加上如下的 export:
module.exports = PropertyView;
返回到 SearchResults.js 文件,在顶部,require React 的下面,添加一个新的 require 语句。
var PropertyView = require('./PropertyView');
接下来更新 rowPassed(),添加跳转到新加入的 PropertyView:
rowPressed(propertyGuid) {
var property = this.props.listings.filter(prop => prop.guid === propertyGuid)[0];
this.props.navigator.push({
title: "Property",
component: PropertyView,
passProps: {property: property}
});
}
你知道的:回到模拟器,Cmd + R,一路通过搜索点击一行到房产详情界面:
物廉价美——看上去很不错哦!应用即将完成,最后一步是允许用户搜索附近的房产。