react-native自定義組件

react native在app開發(fā)上的一個優(yōu)勢就是組件化開發(fā),當有了足夠多的自定義組件后,可以很方便的將這些組件拼裝起來,開發(fā)效率提高很多。本文中將以一個picker為例子,來講如何包裝一個通用性很強的react native組件。本文的示例源碼可以在ReactNativeUIComponents下載。這個項目未來會不斷的維護加入更多實用的組件,也力求這個項目可以作為一個react native的示例項目,包含了react native開發(fā)中常用的router,navigator,code push等,可以作為參考。

</br>
可以在我的博客http://haiyangjiajian.com/交流更多相關內容。


picker的效果

![picker2.png](http://upload-images.jianshu.io/upload_images/3249059-f9d971aa9a938fa4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

其中picker要展示的內容,百度、搜狗、谷歌等均可以由父組件指定,其樣式也可以由父組件指定。

組件包裝

界面

本文封裝了一個叫Picker的組件。一般推薦通過定義defaultProps來告訴組件的調用者,可以傳入這個組件中的參數有哪些??梢钥吹娇梢詡魅氲膮涤衧tyle:組件樣式;animationType:動畫類型;transparent:是否透明;modalVisible:是否可見;dataArray:顯示的數據;title:標題。可以通過傳入這些參數,使這個組件擁有不同的樣式,顯示不同的數據。

static defaultProps = {
    style: View.propTypes.style,
    animationType: 'none',
    transparent: true,
    modalVisible: true,
    dataArray: [],
    title: 'title'
  };

  constructor(props) {
    super(props);

    this.state = {
      dataSource: this._getDataSource(props.dataArray),
      style: this.props.style,
      animationType: this.props.animationType,
      transparent: this.props.transparent,
      modalVisible: this.props.modalVisible,
    };
  }

組件內部的渲染代碼如下,主體是一個Modal,然后是一個整體的view

<View style={[styles.modalContainer, {backgroundColor: 'rgba(0, 0, 0, 0.5)'}]}>

在這個view中主要有兩部分內容,一個是頂部的title,另一個是底部的listview,title顯示從父組件中傳入的標題,listview顯示傳入的dataArray。

<Modal
        animationType={this.state.animationType}
        transparent={this.state.transparent}
        visible={this.state.modalVisible}
        onRequestClose={() => {this._setModalVisible(false)}}>
        <View style={[styles.modalContainer, {backgroundColor: 'rgba(0, 0, 0, 0.5)'}]}>
          <View style={styles.viewContainer}>
            <View style={styles.titleRow}>
              <TouchableOpacity style={styles.cancelButton} onPress={() => {this._setModalVisible(false)}}>
                <Image style={styles.image}
                       source={require('../img/icon_cancel_grey.png')}/>
              </TouchableOpacity>
              <Text style={[styles.titleText, styles.modalTitle]}>{this.props.title}</Text>
            </View>
            <View style={[{marginTop: 0, marginBottom: 0}]}/>
            <ListView
              style={styles.flex}
              dataSource={this.state.dataSource}
              renderRow={(rowData, sectionID, rowID) => this._renderRow(rowData, sectionID, rowID)}
              renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}
              renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={[GlobalStyles.divider, {marginTop: 0, marginBottom: 0, marginLeft: 16}]}/>}
            />
          </View>
        </View>
</Modal>

listView中每一個cell的渲染

 _renderRow(rowData, sectionID, rowID) {
    return (
      <TouchableHighlight onPress={() => this._pressRow(rowData, rowID)} underlayColor='gray'>
        <View>
          <View style={styles.row}>
            <Text style={styles.rowTitle}>
              {rowData.name}
            </Text>
          </View>
        </View>
      </TouchableHighlight>
    );
  }

下面是對這個組件調用的一個示例,puperseItems是一個格式化對象的數組,這個對象包含了name,id,url三個屬性

<Picker
            title="選擇搜索引擎"
            dataArray={purposeItems}
            selectedData={(purpose) => {this.onPurposeSelected(purpose);}}
            onHideModal={() => this.setState({purposeModalVisible: false})}
/>

至此界面的展示完畢

操作

這樣一個組件主要有兩種操作,點擊當前列和關閉modal,如下兩個函數,主要是調用了父組件傳遞進來的selectedData和onHideModal回調

  _pressRow(rowData, rowID) {
    this.props.selectedData && this.props.selectedData(rowData);
    this.props.selectedIndex && this.props.selectedIndex(rowID);
  }

  _setModalVisible(visible) {
    this.setState({modalVisible: visible});
    if (visible) {
      this.props.onShowModal && this.props.onShowModal();
    } else {
      this.props.onHideModal && this.props.onHideModal();
    }
  }

至此完成了一個組件的封裝,可以靈活的顯示父組件傳入的數據,并進行各種交互。

本文的示例源碼可以在ReactNativeUIComponents下載

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容