最近有个React-native项目需要添加定位功能,看了网上很多相关得帖子,基本都是桥接的3方的SDK ,而且有些功能不能定制,考虑到以后百度SDK版本更新的问题,以及方便后期维护,决定自己桥接一下百度原生定位功能
1.React-Native桥接Android原生UI 组件和原生模块
具体步骤
- 创建一个继承React-Native ViewGroupManager 的 java 类
//MapViewManager.java
public class MapViewManager extends ViewGroupManager<MapView> {
}
- 重写 getName 方法,返回一个字符串,对应JavaScript 中requireNativeComponent 的对象
//MapViewManager.java
@Override
public String getName() {
return "MSMapView";
}
- 重写 createViewInstance 方法,返回自定义的原生组件
//MapViewManager.java
@Override
protected MapView createViewInstance(ThemedReactContext themedReactContext) {
//创建自定义的MapView
}
- 导出视图的属性设置器:通过@ReactProp 注解
//MapViewManager.java
@ReactProp(name = "posLatitude")
public void setPosLatitude(MapView mapView, double posLatitude) {
mStopLatitude = posLatitude;
}
- 对应JavaScript 模块调用
//MapView.js
MapView.propTypes = {
posLatitude: PropTypes.number.isRequired
}
- 把视图管理类注册到应用程序包的creatViewManagers里
//MapViewPackage.java
public class MapViewPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new GeolocationModule(reactContext));
return modules;
}
- 在JavaScript 中使用
//MapView.js
import React from 'react'
import { requireNativeComponent } from 'react-native'
import PropTypes from 'prop-types'
const MSMapView = requireNativeComponent('MSMapView', null)
export default function MapView(props) {
return <MSMapView {...props} />
}
MapView.propTypes = {
posLatitude: PropTypes.number.isRequired,
posLongitude: PropTypes.number.isRequired,
posName: PropTypes.string.isRequired,
posAddress: PropTypes.string.isRequired
}
具体参考官方文档原生UI组件
-
1.2 桥接原生模块
- 首先来创建一个原生模块(GeolocationModule) 。一个原生模块是一个继承了ReactContextBaseJavaModule的Java类,它可以实现一些JavaScript所需的功能
//GeolocationModule.java
public class GeolocationModule extends ReactContextBaseJavaModule {
public GeolocationModule(ReactApplicationContext reactContext) {
super(reactContext);
}
}
- 实现getName方法。这个函数用于返回一个字符串名字,这个名字在JavaScript端标记这个模块
//GeolocationModule.java
public String getName() {
return "MSLocationManager";
}