ReactNative實(shí)例 - 房產(chǎn)搜索App

歡迎Follow我的GitHub, 關(guān)注我的簡(jiǎn)書.

React Native 開發(fā)已經(jīng)初見(jiàn)端倪, 可以完成最基本的功能. 通過(guò)開發(fā)一些簡(jiǎn)單的應(yīng)用, 可以更加熟練的掌握 RN 的知識(shí). 本文介紹非常簡(jiǎn)單的一款房產(chǎn)搜索的App, 通過(guò)調(diào)用公開的搜索服務(wù), 把網(wǎng)絡(luò)的數(shù)據(jù)展示在應(yīng)用中. 通過(guò)代碼更多的了解 RN 的特性.

Logo

已經(jīng)實(shí)現(xiàn) iOS 版本, 僅供學(xué)習(xí)和參考, 可以直接運(yùn)行, 但是 RN 變化較快, 可能不兼容. 關(guān)于在運(yùn)行項(xiàng)目中可能出現(xiàn)的問(wèn)題, 請(qǐng)參考.

主要內(nèi)容:

  1. 使用Navigator棧跳轉(zhuǎn)頁(yè)面.
  2. 使用fetch請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù).
  3. 使用ListView展示列表數(shù)據(jù).

本文源碼的GitHub下載地址


配置項(xiàng)目

初始化 React Native 的項(xiàng)目.

react-native init WclPropertyFinder

修改 Android 的 Gradle 構(gòu)建版本.

dependencies {
    classpath 'com.android.tools.build:gradle:1.2.3'
}

運(yùn)行 iOS 和 Android 項(xiàng)目.

調(diào)試: iOS 模擬機(jī), Cmd + R 重新加載, Cmd + D 模擬晃動(dòng); Android, 晃動(dòng)手機(jī).

修改index.ios.js的內(nèi)容, 設(shè)置啟動(dòng)模塊. 使用NavigatorIOS加載組件搜索頁(yè)SearchPage.

// 使用Navigator管理組件, 注意: 不要糾結(jié)于跨平臺(tái), 學(xué)習(xí)為主
class WclPropertyFinderApp extends React.Component {
  render() {
    return (
      <React.NavigatorIOS
        style={styles.container}
        initialRoute={{
          title: '搜房產(chǎn)',
          component: SearchPage,
        }}/>
    );
  }
}

注冊(cè)組件WclPropertyFinderApp至應(yīng)用WclPropertyFinder.

React.AppRegistry.registerComponent('WclPropertyFinder', () => WclPropertyFinderApp);

首頁(yè)搜索

搜索頁(yè)(SearchPage)包含一個(gè)搜索庫(kù), 可以使用地址或郵編搜索英國(guó)的房產(chǎn)信息.

通過(guò)輸入框的參數(shù)創(chuàng)建網(wǎng)絡(luò)請(qǐng)求URL, 并把請(qǐng)求發(fā)送出去, 獲取信息.

function urlForQueryAndPage(key, value, pageNumber) {
  var data = {
    country: 'uk',
    pretty: '1',
    encoding: 'json',
    listing_type: 'buy',
    action: 'search_listings',
    page: pageNumber
  };

  data[key] = value;

  var querystring = Object.keys(data)
    .map(key => key + '=' + encodeURIComponent(data[key]))
    .join('&');
  return 'http://api.nestoria.co.uk/api?' + querystring;
}

在獲取網(wǎng)絡(luò)請(qǐng)求URL后, 使用fetch函數(shù)獲取數(shù)據(jù).

  _executeQuery(query) {
    console.log(query);
    this.setState({isLoading: true});

    // 網(wǎng)絡(luò)請(qǐng)求
    fetch(query)
      .then(response => response.json())
      .then(json => this._handleResponse(json.response))
      .catch(error => this.setState({
        isLoading: false,
        message: 'Something bad happened ' + error
      }));
  }

處理返回的Json數(shù)據(jù), 使用Navigator跳轉(zhuǎn)到搜索結(jié)果SearchResults頁(yè)面.

  _handleResponse(response) {
    this.setState({isLoading: false, message: ''});
    if (response.application_response_code.substr(0, 1) === '1') {
      console.log('Properties found: ' + response.listings.length);

      // 使用listings調(diào)用結(jié)果頁(yè)面SearchResults
      this.props.navigator.push({
        title: '搜索結(jié)果',
        component: SearchResults,
        passProps: {listings: response.listings}
      });
    } else {
      this.setState({message: 'Location not recognized; please try again.'});
    }
  }

搜索結(jié)果

把獲取的房產(chǎn)信息, 逐行渲染并顯示于ListView中.

  renderRow(rowData, sectionID, rowID) {
    var price = rowData.price_formatted.split(' ')[0];
    return (
      <TouchableHighlight
        onPress={()=>this.rowPressed(rowData.guid)}
        underlayColor='#dddddd'>
         // 布局...
      </TouchableHighlight>
    );
  }

ListView設(shè)置數(shù)據(jù)源dataSource, 每行渲染renderRow.

  render() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderRow.bind(this)}
        />
    );
  }

點(diǎn)擊ListView的行, 可以跳轉(zhuǎn)至房產(chǎn)信息頁(yè)面.

  rowPressed(propertyGuid) {
    var property = this.props.listings.filter(prop => prop.guid === propertyGuid)[0];
    this.props.navigator.push({
      title: '房產(chǎn)信息',
      component: PropertyView,
      passProps: {property: property}
    });
  }

房產(chǎn)信息

房產(chǎn)信息是單純顯示頁(yè)面, 顯示圖片和文字內(nèi)容.

class PropertyView extends Component {
  render() {
    var property = this.props.property; // 由SearchResult傳遞的搜索結(jié)果
    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 (
       // 布局...
    );
  }
}

最終效果

動(dòng)畫

使用 RN 開發(fā)應(yīng)用非??旖? 復(fù)用邏輯到多個(gè)平臺(tái), 節(jié)省開發(fā)成本, 不過(guò)目前正在完善中.

本文參考我的朋友Tom的一篇文章.

OK, that's all! Enjoy it!

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

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,351評(píng)論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,694評(píng)論 4 61
  • 在swift 中g(shù)et,set被稱之為“計(jì)算屬性”,它用來(lái)間接獲取/改變其他屬性的值。 set 和get 是針對(duì)...
    WMSmile閱讀 3,407評(píng)論 0 1
  • 08六項(xiàng)日精進(jìn)打卡姓名:劉海北京多禾餐飲管理有限公司組別 249期謙虛1組【日精進(jìn)打卡第0094天】【知~學(xué)習(xí)】誦...
    七天樂(lè)餐閱讀 137評(píng)論 0 0
  • 這些畫用什么來(lái)形容呢 野芳發(fā)而幽香,佳木秀而繁陰 午日步西園,繁花亂相照 百花掃地,紅紫踐為塵 好了,編不下去了 ...
    藝伙閱讀 510評(píng)論 0 2

友情鏈接更多精彩內(nèi)容