React Native 學習指南(三) - 把玩更多UI元件

Binboy_王興彬發表於2016-11-30

在之前的天氣小應用實戰中,我們已經基本瞭解一些基礎元件的使用:<View><Text><Image>,接下來我們通過官方示例 UIExplorer 看看觸控手勢這樣在移動裝置上的常用操作將怎樣在 React Native 中實現,再嘗試 <ListView><TabView><NavigatorView> 這些進階元件。

React Native 學習指南(三) - 把玩更多UI元件
官方示例 UIExplorer

觸控操作 (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。

新增列表檢視元件,有兩個必要屬性: dataSourcerenderRow,也就是資料來源以及渲染列表單元元件。


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 ,我們可以瞭解更多更多元件來支援特定功能的實現。接下來,就要征戰最令人頭疼的樣式佈局了。

相關文章