Tích hợp Map trong React Native

Giới thiệu

Bài viết này mình sẽ giới thiệu cho các bạn việc tích hợp Map vào React Native App với thư viện react-native-maps.

Với thư viện này thì trên thiết bị Android sẽ sử dụng Google Maps, còn trên thiết bị iOS có thể sử dụng Google Maps hoặc Apple Map.

Cài đặt

Đầu tiên, hãy chạy lệnh sau để cài đặt thư viện:

npm install react-native-maps --save

hoặc

yarn add react-native-maps

Cấu hình trên iOS


Sử dụng React Native Link (React Native <= 0.59)

Chạy lệnh react-native link react-native-maps để link thư viện, chạy xong là chúng ta có thể sử dụng thư viện này trên iOS

Sử dụng CocoaPods (React Native <= 0.59)

Sửa Podfile ở thư mục ios/Podfile, thay thế _YOUR_PROJECT_TARGET_ với target project của bạn (mặc định là tên project)

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target '_YOUR_PROJECT_TARGET_' do
  rn_path = '../node_modules/react-native'
  rn_maps_path = '../node_modules/react-native-maps'

  # See http://facebook.github.io/react-native/docs/integration-with-existing-apps.html#configuring-cocoapods-dependencies
  pod 'yoga', path: "#{rn_path}/ReactCommon/yoga/yoga.podspec"
  pod 'React', path: rn_path, subspecs: [
    'Core',
    'CxxBridge',
    'DevSupport',
    'RCTActionSheet',
    'RCTAnimation',
    'RCTGeolocation',
    'RCTImage',
    'RCTLinkingIOS',
    'RCTNetwork',
    'RCTSettings',
    'RCTText',
    'RCTVibration',
    'RCTWebSocket',
  ]

  # React Native third party dependencies podspecs
  pod 'DoubleConversion', :podspec => "#{rn_path}/third-party-podspecs/DoubleConversion.podspec"
  pod 'glog', :podspec => "#{rn_path}/third-party-podspecs/glog.podspec"
  # If you are using React Native <0.54, you will get the following error:
  # "The name of the given podspec `GLog` doesn't match the expected one `glog`"
  # Use the following line instead:
  #pod 'GLog', :podspec => "#{rn_path}/third-party-podspecs/GLog.podspec"
  pod 'Folly', :podspec => "#{rn_path}/third-party-podspecs/Folly.podspec"

  # react-native-maps dependencies
  pod 'react-native-maps', path: rn_maps_path
  # pod 'react-native-google-maps', path: rn_maps_path  # Uncomment this line if you want to support GoogleMaps on iOS
  # pod 'GoogleMaps'  # Uncomment this line if you want to support GoogleMaps on iOS
  # pod 'Google-Maps-iOS-Utils' # Uncomment this line if you want to support GoogleMaps on iOS
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == 'react-native-google-maps'
      target.build_configurations.each do |config|
        config.build_settings['CLANG_ENABLE_MODULES'] = 'No'
      end
    end
  end
end

Sau đó chạy các lệnh:

cd ios
pod install

và mở file workspace (.xcworkspace) ở XCode để build project.

Sử dụng CocoaPods (React Native >= 60)

Đối với React Native phiên bản >= 60 thì bạn chỉ cần chạy các lệnh:

cd ios
pod install

Cấu hình trên Android

  1. (React Native <= 0.59) thêm react-native-maps project vào android/settings.gradle:
...
include ':react-native-maps'
project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/lib/android')
  1. (React Native <= 0.59) thêm dependency react-native-maps vào android/app/build.gradle:
...
dependencies {
  ...
  implementation project(':react-native-maps')
}
  1. Thêm dependency gms service vào android/app/build.gradle:
...
dependencies {
   ...
   implementation(project(':react-native-maps')){
       exclude group: 'com.google.android.gms', module: 'play-services-base'
       exclude group: 'com.google.android.gms', module: 'play-services-maps'
   }
   implementation 'com.google.android.gms:play-services-base:17.2.1'
   implementation 'com.google.android.gms:play-services-maps:17.0.0'
}
  1. Thêm Google Map API Key vào file manifest (android/app/src/main/AndroidManifest.xml)
<application>
   <!-- You will only need to add this meta-data tag, but make sure it's a child of application -->
   <meta-data
     android:name="com.google.android.geo.API_KEY"
     android:value="Your Google maps API Key Here"/>
  
   <!-- You will also only need to add this uses-library tag -->
   <uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>

Để lấy API Key: https://developers.google.com/maps/documentation/android-api/signup

  1. (React Native <= 0.59) Thêm import com.airbnb.android.react.maps.MapsPackage;new MapsPackage() vào file MainApplication.java:
import com.airbnb.android.react.maps.MapsPackage;
...
    @Override
    protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                new MapsPackage()
        );
    }

Sử dụng

Thư việnreact-native-maps cung cấp các component:

Sử dụng chung

import MapView from 'react-native-maps';

Component MapView chính là component cha, được dựng lên từ các component khác như Marker, Polygon ... là component con của MapView

Render Map với khu vực khởi tạo

Với kinh độ (logitude) và vĩ độ (latitude) cho trước ta có thể render Map hiển thị:

 <MapView
    initialRegion={{
      latitude: 37.78825,
      longitude: -122.4324,
      latitudeDelta: 0.0922,
      longitudeDelta: 0.0421,
    }}
  />

Render Map khi thay đổi khu vực

getInitialState() {
  return {
    region: {
      latitude: 37.78825,
      longitude: -122.4324,
      latitudeDelta: 0.0922,
      longitudeDelta: 0.0421,
    },
  };
}

onRegionChange(region) {
  this.setState({ region });
}

render() {
  return (
    <MapView
      region={this.state.region}
      onRegionChange={this.onRegionChange}
    />
  );
}

Render các Marker:

import { Marker } from 'react-native-maps';

<MapView
  region={this.state.region}
  onRegionChange={this.onRegionChange}
>
  {this.state.markers.map(marker => (
    <Marker
      coordinate={marker.latlng}
      title={marker.title}
      description={marker.description}
    />
  ))}
</MapView>

Render Marker với custom image:

<Marker
  coordinate={marker.latlng}
  image={require('../assets/pin.png')}
/>

Lấy Snapshot Map

import MapView, { Marker } from 'react-native-maps';

getInitialState() {
  return {
    coordinate: {
      latitude: LATITUDE,
      longitude: LONGITUDE,
    },
  };
}

takeSnapshot () {
  // 'takeSnapshot' takes a config object with the
  // following options
  const snapshot = this.map.takeSnapshot({
    width: 300,      // optional, when omitted the view-width is used
    height: 300,     // optional, when omitted the view-height is used
    region: {..},    // iOS only, optional region to render
    format: 'png',   // image formats: 'png', 'jpg' (default: 'png')
    quality: 0.8,    // image quality: 0..1 (only relevant for jpg, default: 1)
    result: 'file'   // result types: 'file', 'base64' (default: 'file')
  });
  snapshot.then((uri) => {
    this.setState({ mapSnapshot: uri });
  });
}

render() {
  return (
    <View>
      <MapView initialRegion={...} ref={map => { this.map = map }}>
        <Marker coordinate={this.state.coordinate} />
      </MapView>
      <Image source={{ uri: this.state.mapSnapshot.uri }} />
      <TouchableOpacity onPress={this.takeSnapshot}>
        Take Snapshot
      </TouchableOpacity>
    </View>
  );
}

Kết luận

Còn rất nhiều tính năng với map được hỗ trợ bởi thư viện này, mời bạn tham khảo thêm tại: https://github.com/react-native-community/react-native-maps


All Rights Reserved