在之前的天气小应用实战中,我们已经基本了解一些基础组件的使用:<View>、<Text>、<Image>,接下来我们通过官方示例 UIExplorer 看看触摸和手势这样在移动设备上的常用操作将怎样在 React Native 中实现,再尝试 <ListView>、<TabView>、<NavigatorView> 这些进阶组件。

触控操作 (TouchableHighlight)
要让组件实现触控操作,使用
<TouchableHighlight>对组件进行包装即可,并制定onPress等操作响应方法。
// 参见 https://github.com/facebook/react-native/blob/master/Examples/UIExplorer/js/TouchableExample.js
<TouchableHighlight
style={styles.wrapper}
onPress={() => console.log('stock THW image - highlight')}>
<Image source={heartImage} style={styles.image}/>
</TouchableHighlight>手势响应 (GestureResponder)
和 iOS 中手势系统一样,GestureResponder 是一个相对抽象的底层接口,这里我们将通过了解基于此的更高层实现的 PanResponder 来理解手势响应。
不同于
<TouchableHighlight>,PanResponder并不是组件,而是一个类。
_panResponder: {}, // 声明一个 PanResponder 变量
// 创建 PanRespondre 实例,并实现相关响应操作方法
componentWillMount: function() {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
onPanResponderGrant: this._handlePanResponderGrant,
onPanResponderMove: this._handlePanResponderMove,
onPanResponderRelease: this._handlePanResponderEnd,
onPanResponderTerminate: this._handlePanResponderEnd,
});
},在
render函数中给视图组件添加手势
render: function() {
return (
<View
style={styles.container}>
<View
style={styles.circle}
{...this._panResponder.panHandlers}
/>
</View>以上手势触控操作都只是参照官方示例做简单梳理,更多具体的代码实现可参见 UIExplorer
使用 <ListView> 组件
列表视图,即 iOS 开发中的 TableView。
添加列表视图组件,有两个必要属性:
dataSource和renderRow,也就是数据源以及渲染列表单元组件。
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
return {
dataSource: ds.cloneWithRows(this._genRows({})),
};
},
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
/>
_renderRow: function(rowData: string, sectionID: number, rowID: number, highlightRow: (sectionID: number, rowID: number) => void) {
var rowHash = Math.abs(hashCode(rowData));
var imgSource = THUMB_URLS[rowHash % THUMB_URLS.length];
return (
<TouchableHighlight onPress={() => {
this._pressRow(rowID);
highlightRow(sectionID, rowID);
}}>
<View>
<View style={styles.row}>
<Image style={styles.thumb} source={imgSource} />
<Text style={styles.text}>
{rowData + ' - ' + LOREM_IPSUM.substr(0, rowHash % 301 + 10)}
</Text>
</View>
</View>
</TouchableHighlight>
);
},
_genRows: function(pressData: {[key: number]: boolean}): Array<string> {
var dataBlob = [];
for (var ii = 0; ii < 100; ii++) {
var pressedText = pressData[ii] ? ' (pressed)' : '';
dataBlob.push('Row ' + ii + pressedText);
}
return dataBlob;
},原理和使用 UITableView 大相径庭,熟悉了之后并不难理解。官方示例参见:ListViewExample.js
使用 Navigator
即类似 iOS 中的 NavigationController。允许应用在不同屏幕之间切换“场景(Scene)”,通过一个“栈”来维护场景的推入(push)和弹出(pop)。参见官方示例 Navigator
平台特定组件
React-Native 的一大特点就是支持跨平台开发,但是由于 iOS 与 Android 交互方式之间存在差异,因此还需要针对不同平台使用特定组件。一般这些平台特定组件都有相应平台的后缀标识,例如 <TabBarIOS> 和 <SwitchAndroid>。
总结
通过官方示例 UIExplorer ,我们可以了解更多更多组件来支持特定功能的实现。接下来,就要征战最令人头疼的样式布局了。