React Native 實例 - 房產搜索

ctpy9661 8年前發布 | 15K 次閱讀 ReactNative 移動開發 React Native

 

React Native 開發已經初見端倪, 可以完成最基本的功能. 通過開發一些簡單的應用, 可以更加熟練的掌握 RN 的知識. 本文介紹非常簡單的一款 房產搜索 的App, 通過調用公開的搜索服務, 把網絡的數據展示在應用中. 通過代碼更多的了解 RN 的特性.

更多: http://www.wangchenlong.org/

歡迎Follow我的GitHub: https://github.com/SpikeKing

已經實現 iOS 版本, 僅供學習和參考, 可以直接運行, 但是 RN 變化較快, 可能不兼容. 關于在運行項目中可能出現的問題, 請參考.

本文源碼的GitHub 下載地址

配置

初始化 React Native 的項目.

react-native init WclPropertyFinder

修改 Android 的 Gradle 構建版本.

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

運行 iOS 和 Android 項目.

調試: iOS 模擬機, Cmd + R 重新加載, Cmd + D 模擬晃動; Android, 晃動手機.

修改 index.ios.js 的內容, 啟動新的模塊.

'use strict';

var React = require('react-native');

// 搜索頁面
var SearchPage = require('./SearchPage')

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

// 樣式
var styles = React.StyleSheet.create({
 text: {
 color: 'black',
 backgroundColor: 'white',
 fontSize: 30,
 margin: 80
 },
 container: {
 flex: 1
 }
});

// 注冊組件
React.AppRegistry.registerComponent('WclPropertyFinder', () => WclPropertyFinderApp);

搜索頁

搜索頁(SearchPage)包含一個搜索庫, 可以使用地址或郵編搜索英國的房產信息.

通過輸入框的參數創建網絡請求URL, 并把請求發送出去, 獲取信息.

/**
 * 訪問網絡服務的Api, 拼接參數
 * 輸出: http://api.nestoria.co.uk/api?country=uk&pretty=1&encoding=json&listing_type=buy&action=search_listings&page=1&place_name=London
 *
 * @param key 最后一個參數的鍵, 用于表示地理位置
 * @param value 最后一個參數的值, 具體位置
 * @param pageNumber page的頁面數
 * @returns {string} 網絡請求的字符串
 */
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;
}

獲取信息以后, 使用 Navigator 跳轉到搜索結果頁面, 使用 ListView 顯示詳細內容.

/**
 * 執行網絡請求, 下劃線表示私有
 * @param query url
 * @private
 */
_executeQuery(query) {
  console.log(query);
  this.setState({isLoading: true});

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

/**
 * 處理網絡請求的回調
 * @param response 請求的返回值
 * @private
 */
_handleResponse(response) {
  this.setState({isLoading: false, message: ''});
  if (response.application_response_code.substr(0, 1) === '1') {
    console.log('Properties found: ' + response.listings.length);

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

搜索結果

把獲取的房產信息, 逐行顯示于ListView中.

/**
 * 渲染列表視圖的每一行
 * @param rowData 行數據
 * @param sectionID 塊ID
 * @param rowID 行ID
 * @returns {XML} 頁面
 */
renderRow(rowData, sectionID, rowID) {
  var price = rowData.price_formatted.split(' ')[0];
  return (
    <TouchableHighlight
      onPress={()=>this.rowPressed(rowData.guid)}
      underlayColor='#dddddd'>
      <View style={styles.rowContainer}>
        <Image style={styles.thumb} source={{uri:rowData.img_url}}/>
        <View style={styles.textContainer}>
          <Text style={styles.price}>${price}</Text>
          <Text style={styles.title} numberOfLines={1}>
            {rowData.title}
          </Text>
        </View>
      </View>
    </TouchableHighlight>
  );
}

/**
 * 渲染, 每行使用renderRow渲染
 * @returns {XML} 結果頁面的布局
 */
render() {
  return (
    <ListView
      dataSource={this.state.dataSource}
      renderRow={this.renderRow.bind(this)}
      />
  );
}

點擊ListView的行, 可以跳轉至 房產信息 頁面.

/**
 * 點擊每行, 通過行數選擇信息
 * @param propertyGuid 行ID
 */
rowPressed(propertyGuid) {
  var property = this.props.listings.filter(prop => prop.guid === propertyGuid)[0];

  this.props.navigator.push({
    title: '房產信息',
    component: PropertyView,
    passProps: {property: property}
  });
}

房產信息

房產信息是單純顯示頁面, 顯示圖片和文字內容.

class PropertyView extends Component {
  render() {
    var property = this.props.property; // 由SearchResult傳遞的搜索結果
    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 (
      <View style={styles.container}>
        <Image style={styles.image}
               source={{uri: property.img_url}}/>
        <View style={styles.heading}>
          <Text style={styles.price}>${price}</Text>
          <Text style={styles.title}>{property.title}</Text>
          <View style={styles.separator}/>
        </View>
        <Text style={styles.description}>{stats}</Text>
        <Text style={styles.description}>{property.summary}</Text>
      </View>
    );
  }
}

最終效果

使用 RN 開發應用非常快捷, 可以復用代碼邏輯到多個平臺.

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

OK, that’s all! Enjoy it!

 

來自: http://www.wangchenlong.org/2016/04/12/1604/121-rn-property-demo/

 本文由用戶 ctpy9661 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!