在之前的天氣小應用實戰中,我們已經基本瞭解一些基礎元件的使用:<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 ,我們可以瞭解更多更多元件來支援特定功能的實現。接下來,就要征戰最令人頭疼的樣式佈局了。