react-native-smart-amap
A AMap Library for React Native apps.
react-native 高德地图SDK 插件, 支持ios与android, 关于使用高德地图SDK, 申请应用key等详细信息请点击这里
Mac下Android Studio中获取SHA1和MD5请点击这里
预览
安装
npm install react-native-smart-amap --save
Notice
这个版本仅支持react-native 0.40及以上, 如果你想使用旧版本,使用npm install [email protected] --save
安装 (iOS)
-
将RCTAMap.xcodeproj作为Library拖进你的Xcode里的project中.
-
将RCTAMap目录里Frameworks目录拖进主project目录下, 选择copy items if needed, create groups, 另外add to target不要忘记选择主project.
-
将RCTAMap目录里Frameworks目录里的AMap.bundle拖进主project目录下, 选择copy items if needed, create groups, 另外add to target不要忘记选择主project.
-
点击你的主project, 选择Build Phases -> Link Binary With Libraries, 将RCTAMap.xcodeproj里Product目录下的libRCTAMap.a拖进去.
-
同上位置, 选择Add items, 将系统库libstdc++.6.0.9.tbd加入.
-
同上位置, 选择Add items, 将系统库libc++.tbd加入.
-
同上位置, 选择Add items, 将系统库libz.tbd加入.
-
同上位置, 选择Add items, 将系统库Security.framework加入.
-
同上位置, 选择Add items, 将系统库CoreTelephony.framework加入.
-
同上位置, 选择Add items, 将系统库SystemConfiguration.framework加入.
-
同上位置, 选择Add items, 将系统库JavaScriptCore.framework加入.
-
同上位置, 选择Add items, 将系统库CoreLocation.framework加入.
-
选择Build Settings, 找到Header Search Paths, 确认其中包含$(SRCROOT)/../../../react-native/React, 模式为recursive.
-
同上位置, 找到Framework Search Paths, 加入$(PROJECT_DIR)/Frameworks.
-
点击在Libraries下已拖进来的RCTAMap.xcodeproj, 选择Build Settings, 找到Framework Search Paths, 将$(SRCROOT)/../../../ios/Frameworks替换成$(SRCROOT)/../../../../ios/Frameworks.
-
在
info.plist
中加入Privacy - Location When In Use Usage Description
属性(ios 10) -
在
info.plist
中加入Allow Arbitrary Loads
属性, 并设置值为YES(ios 10) -
在
AppDelegate.m
中
...
#import <AMapFoundationKit/AMapFoundationKit.h> //引入高德地图核心包
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[AMapServices sharedServices].apiKey = @"请填写您的key"; //设置高德地图SDK服务key
...
}
...
安装 (Android)
- 在
android/settings.gradle
中
...
include ':react-native-smart-amap'
project(':react-native-smart-amap').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-smart-amap/android')
- 在
android/app/build.gradle
中
...
dependencies {
...
// From node_modules
compile project(':react-native-smart-amap')
}
- 在
MainApplication.java
中
...
import com.reactnativecomponent.amaplocation.RCTAMapPackage; //import package
...
/**
* A list of packages used by the app. If the app uses additional views
* or modules besides the default ones, add more packages here.
*/
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RCTAMapPackage() //register Module
);
}
...
- 在
AndroidManifest.xml
中, 加入所需权限
...
<!--*************************高德地图-定位所需要权限*************************-->
<!-- Normal Permissions 不需要运行时注册 -->
<!--获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<!-- 请求网络 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 不是SDK需要的权限,是示例中的后台唤醒定位需要的权限 -->
<!--<uses-permission android:name="android.permission.WAKE_LOCK" />-->
<!-- 需要运行时注册的权限 -->
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--用于提高GPS定位速度-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!--写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--读取缓存数据-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 更改设置 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!--*************************高德地图-定位所需要权限*************************-->
...
- 在
AndroidManifest.xml
中, application标签内加入
...
<!--高德地图SDK key设置-->
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="请填写您的key"/>
<!--高德地图APS服务设置-->
<service android:name="com.amap.api.location.APSService" >
</service>
...
完整示例
点击这里 ReactNativeComponentDemos
使用简介
Install the package from npm with npm install react-native-smart-amap --save
.
Then, require it from your app's JavaScript files with import Barcode from 'react-native-smart-amap'
.
import React, {
Component,
} from 'react'
import {
StyleSheet,
View,
Text,
Image,
NativeAppEventEmitter,
TouchableHighlight,
ListView,
Dimensions,
Alert,
Platform,
} from 'react-native'
import AMapLocation from 'react-native-smart-amap-location'
import AMap from 'react-native-smart-amap'
import Button from 'react-native-smart-button'
import AppEventListenerEnhance from 'react-native-smart-app-event-listener-enhance'
import PullToRefreshListView from 'react-native-smart-pull-to-refresh-listview'
import TimerEnhance from 'react-native-smart-timer-enhance'
import AMapALoneNearByList from './amp-alone-nearby-list'
import ListViewActivityIndicator from './ListViewActivityIndicator'
const {width: deviceWidth, height: deviceHeight} = Dimensions.get('window')
class AMapDemo extends Component {
constructor(props) {
super(props);
this._amap = null
this._page = 0
this._coordinate = this.props.navigator.navigationContext._currentRoute.coordinate
console.log(`this._coordinate -> `)
console.log(this._coordinate)
this._keywords = '商务住宅|学校'
this._onDidMoveByUserTimer = null
}
componentDidMount() {
this.addAppEventListener(
NativeAppEventEmitter.addListener('amap.location.onLocationResult', this._onLocationResult),
NativeAppEventEmitter.addListener('amap.onPOISearchDone', this._onPOISearchDone)
//NativeAppEventEmitter.addListener('amap.onPOISearchFailed', this._onPOISearchFailed)
)
}
render () {
//console.log(`amap-alone render...`)
return (
<View style={{marginTop: (Platform.OS == 'ios' ? 20 + 44 : 56), flex: 1, }}>
<View style={{position: 'relative', height: (deviceHeight - (Platform.OS == 'ios' ? 64 : 56)) - 50 * 5,}}>
<AMap
ref={ component => this._amap = component }
style={{flex: 1, }}
options={{
frame: {
width: deviceWidth,
height: (deviceHeight - 64) - 50 * 5
},
showsUserLocation: false,
userTrackingMode: Platform.OS == 'ios' ? AMap.constants.userTrackingMode.none : null,
centerCoordinate: {
latitude: this._coordinate.latitude,
longitude: this._coordinate.longitude,
},
zoomLevel: 18.1,
centerMarker: Platform.OS == 'ios' ? 'icon_location' : 'poi_marker',
}}
onLayout={this._onLayout}
onDidMoveByUser={this._onDidMoveByUser}
/>
<Button
touchableType={Button.constants.touchableTypes.highlight}
underlayColor={'#ccc'}
style={{padding: 5, position: 'absolute', left: 10, bottom: 20, backgroundColor: '#fff', justifyContent: 'center', borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: '#ffffff', justifyContent: 'center', }}
onPress={ () => {
AMapLocation.init(null)
AMapLocation.getLocation()
//this._activityIndicator.setState({ visible: true,})
}}>
<Image source={{uri: Platform.OS == 'ios' ? 'gpsStat1' : 'gps_stat1'}} style={{width: 28, height: 28,}}/>
</Button>
</View>
<View style={{flex: 1, position: 'relative',}}>
<AMapALoneNearByList
ref={ (component) => this._amapALoneNearByList = component }
onRefresh={this._onRefresh}
onLoadMore={this._onLoadMore}
/>
<ListViewActivityIndicator
ref={ (component) => this._activityIndicator = component }
style={{marginRight: 10, position:'absolute', left: (deviceWidth - 20) / 2, top: (50 * 5 - 20) / 2, }}
color={'#a9a9a9'}/>
</View>
</View>
)
}
_onDidMoveByUser = (e) => {
//console.log(`_onDidMoveByUser....`)
if(this._onDidMoveByUserTimer) {
this.clearTimeout(this._onDidMoveByUserTimer)
this._onDidMoveByUserTimer = null
}
let { longitude, latitude, } = e.nativeEvent.data.centerCoordinate
this._onDidMoveByUserTimer = this.setTimeout( ()=> {
let {refresh_none, refresh_idle, load_more_none, load_more_idle, loaded_all,} = PullToRefreshListView.constants.viewState
if((this._amapALoneNearByList._pullToRefreshListView._refreshState == refresh_none || this._amapALoneNearByList._pullToRefreshListView._refreshState == refresh_idle)
&& (this._amapALoneNearByList._pullToRefreshListView._loadMoreState == load_more_none
|| this._amapALoneNearByList._pullToRefreshListView._loadMoreState == load_more_idle
|| this._amapALoneNearByList._pullToRefreshListView._loadMoreState == loaded_all)) {
console.log(`beginRefresh(true)....`)
this._coordinate = {
longitude,
latitude,
}
this._activityIndicator.setState({ visible: true,})
this._amapALoneNearByList._pullToRefreshListView._scrollView.scrollTo({ y: 0, animated: false, })
this._amapALoneNearByList._pullToRefreshListView.beginRefresh(true)
//this._amapALoneNearByList._pullToRefreshListView.beginRefresh()
this._beginRefresh = true
}
}, 300)
}
_onLocationResult = (result) => {
if(result.error) {
console.log(`map-错误代码: ${result.error.code}, map-错误信息: ${result.error.localizedDescription}`)
}
else {
if(result.formattedAddress) {
console.log(`map-格式化地址 = ${result.formattedAddress}`)
}
else {
console.log(`map-纬度 = ${result.coordinate.latitude}, map-经度 = ${result.coordinate.longitude}`)
this._coordinate = {
latitude: result.coordinate.latitude,
longitude: result.coordinate.longitude,
}
this._amap.setOptions({
zoomLevel: 18.1,
})
this._amap.setCenterCoordinate(this._coordinate)
}
}
}
//_onPOISearchFailed = (e) => {
// //console.log(`_onPOISearchFailed...`)
// //console.log(e)
// //console.log(e.error)
// this._page--;
//}
_onPOISearchDone = (result) => {
console.log(`_onPOISearchDone...`)
if(Platform.OS == 'ios') {
this._endSearch(result)
}
else {
this.setTimeout( () => {
this._endSearch(result)
}, 255)
}
}
_endSearch = (result) => {
let { searchResultList, error } = result
console.log(result.error)
if(error) {
if(this._page == 1) {
this._page--
this._amapALoneNearByList._pullToRefreshListView.endRefresh(this._beginRefresh)
//this._amapALoneNearByList._pullToRefreshListView.endRefresh()
this._beginRefresh = false
this._activityIndicator.setState({ visible: false,})
}
else {
this._amapALoneNearByList._pullToRefreshListView.endLoadMore(false)
}
return
}
console.log(`this._page = ${this._page}`)
//onRefresh
if(this._page == 1) {
this._amapALoneNearByList.setState({
dataList: searchResultList,
dataSource: this._amapALoneNearByList._dataSource.cloneWithRows(searchResultList),
})
this._amapALoneNearByList._pullToRefreshListView.endRefresh(this._beginRefresh)
//this._amapALoneNearByList._pullToRefreshListView.endRefresh()
this._beginRefresh = false
this._activityIndicator.setState({ visible: false,})
}
//onLoadMore
else {
let newDataList = this._amapALoneNearByList.state.dataList.concat(searchResultList)
this._amapALoneNearByList.setState({
dataList: newDataList,
dataSource: this._amapALoneNearByList._dataSource.cloneWithRows(newDataList),
})
let loadedAll
if(searchResultList.length == 100) {
loadedAll = true
this._amapALoneNearByList._pullToRefreshListView.endLoadMore(loadedAll)
}
else {
loadedAll = false
this._amapALoneNearByList._pullToRefreshListView.endLoadMore(loadedAll)
}
}
}
_searchNearBy = (searchParams)=> {
this._amap.searchPoiByCenterCoordinate(searchParams)
}
_onRefresh = () => {
console.log(`outer _onRefresh...`)
this._searchNearBy({
page: (this._page = 1),
coordinate: this._coordinate,
keywords: this._keywords,
})
}
_onLoadMore = () => {
console.log(`outer _onLoadMore...`)
this._searchNearBy({
page: ++this._page,
coordinate: this._coordinate,
keywords: this._keywords,
})
}
}
export default TimerEnhance(AppEventListenerEnhance(AMapDemo))
属性
Prop | Type | Optional | Default | Description |
---|---|---|---|---|
options | object | No | 地图参数对象 | |
options.frame | object | No | ios设置地图宽(width), 高(height), 类型是number | |
options.showTraffic | bool | Yes | ios设置是否显示路况, 默认不显示 | |
options.showsUserLocation | bool | Yes | ios设置是否显示用户位置,默认显示 | |
options.userTrackingMode | bool | Yes | ios设置追踪用户位置更新的模式,默认不追踪 | |
options.zoomLevel | number | Yes | 指定缩放级别, 默认为最大级别 | |
options.centerCoordinate | object | Yes | 根据经度(latitude)纬度(longitude)指定地图的中心点, 类型是number | |
options.centerMarker | string | Yes | 设置中心点自定义图标的项目资源名称, 如为空则不显示中心点图标 |
方法
-
setOptions
- 描述: 更改地图参数
- 参数: reactTag 类型: number, 地图的native view id, 根据这个id可以获取到地图的实例
- 参数: options 类型: object, 地图参数, 数据结构同上Props中的options
-
setCenterCoordinate
- 描述: 根据经纬度在地图中心位置显示
- 参数: reactTag 类型: number, 地图的native view id, 根据这个id可以获取到地图的实例
- 参数: coordinate 类型: object, 经纬度坐标参数, 数据结构同上Props中的options.centerCoordinate
-
searchPoiByCenterCoordinate
- 描述: 根据经纬度坐标来搜索周边的POI
- 参数: params 类型: object, 搜索参数, 数据结构如下: * types 类型: string 表示搜索类型,多个类型用“|”分割 可选值:文本分类、分类代码 * sortrule 类型: number 表示排序规则, 0-距离排序;1-综合排序, 默认1 * offset 类型: number 表示每页记录数, 范围1-50, 默认20 * page 类型: number 表示当前页数, 范围1-100, 默认1 * keywords 类型: string 表示查询关键字,多个关键字用“|”分割 * coordinate 类型: object 表示中心点经纬度, 数据结构同上Props中的options.centerCoordinate * radius 类型: int 表示辐射半径, 默认3000米
事件监听
-
地图事件: onDidMoveByUser
- 描述: 监听用户动作, 返回当前地图中心点的经纬度信息
-
全局事件: amap.onPOISearchDone
- 描述: 监听POI搜索回调, 返回周边的POI信息