Commit 83f4f3b8 authored by Qiu Xiang's avatar Qiu Xiang

实现 Marker 的基本功能

parent c78da8a7
......@@ -23,6 +23,8 @@ public class AMap3DPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(new AMapViewManager());
return Arrays.<ViewManager>asList(
new AMapViewManager(),
new AMapMarkerManager());
}
}
package cn.qiuxiang.react.amap3d;
import android.content.Context;
import com.amap.api.maps.AMap;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.BaseDataSubscriber;
import com.facebook.datasource.DataSource;
import com.facebook.datasource.DataSubscriber;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.image.CloseableStaticBitmap;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.views.view.ReactViewGroup;
public class AMapMarker extends ReactViewGroup {
private Marker marker;
private LatLng position;
private String title = "";
private String snippet = "";
private boolean flat = false;
private float opacity = 1;
private boolean draggable = false;
private BitmapDescriptor iconBitmapDescriptor;
private DataSubscriber<CloseableReference<CloseableImage>> dataSubscriber =
new BaseDataSubscriber<CloseableReference<CloseableImage>>() {
@Override
protected void onNewResultImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
CloseableReference<CloseableImage> ref = dataSource.getResult();
if (ref != null) {
try {
iconBitmapDescriptor = BitmapDescriptorFactory.fromBitmap(
((CloseableStaticBitmap) ref.get()).getUnderlyingBitmap());
if (marker != null) {
marker.setIcon(iconBitmapDescriptor);
}
} finally {
CloseableReference.closeSafely(ref);
}
}
}
@Override
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
}
};
public AMapMarker(Context context) {
super(context);
}
public void addToMap(AMap map) {
marker = map.addMarker(getMarkerOptions());
}
private MarkerOptions getMarkerOptions() {
return new MarkerOptions()
.setFlat(flat)
.icon(iconBitmapDescriptor)
.alpha(opacity)
.draggable(draggable)
.position(position)
.title(title)
.snippet(snippet);
}
public void setTitle(String title) {
this.title = title;
if (marker != null) {
marker.setTitle(title);
}
}
public void setSnippet(String snippet) {
this.snippet = snippet;
if (marker != null) {
marker.setSnippet(snippet);
}
}
public void setCoordinate(ReadableMap coordinate) {
position = new LatLng(coordinate.getDouble("latitude"), coordinate.getDouble("longitude"));
if (marker != null) {
marker.setPosition(position);
}
}
public void setFlat(boolean flat) {
this.flat = flat;
if (marker != null) {
marker.setFlat(flat);
}
}
public void setOpacity(float opacity) {
this.opacity = opacity;
if (marker != null) {
marker.setAlpha(opacity);
}
}
public void setDraggable(boolean draggable) {
this.draggable = draggable;
if (marker != null) {
marker.setDraggable(draggable);
}
}
public void setImage(String uri) {
DataSource<CloseableReference<CloseableImage>> dataSource = Fresco
.getImagePipeline().fetchDecodedImage(ImageRequest.fromUri(uri), this);
dataSource.subscribe(dataSubscriber, CallerThreadExecutor.getInstance());
}
}
package cn.qiuxiang.react.amap3d;
import android.view.View;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
class AMapMarkerManager extends SimpleViewManager<View> {
@Override
public String getName() {
return "AMapMarker";
}
@Override
protected View createViewInstance(ThemedReactContext reactContext) {
return new AMapMarker(reactContext);
}
@ReactProp(name = "title")
public void setTitle(AMapMarker marker, String title) {
marker.setTitle(title);
}
@ReactProp(name = "description")
public void setSnippet(AMapMarker marker, String description) {
marker.setSnippet(description);
}
@ReactProp(name = "coordinate")
public void setCoordinate(AMapMarker view, ReadableMap coordinate) {
view.setCoordinate(coordinate);
}
@ReactProp(name = "flat")
public void setFlat(AMapMarker marker, boolean flat) {
marker.setFlat(flat);
}
@ReactProp(name = "opacity")
public void setOpacity(AMapMarker marker, float opacity) {
marker.setOpacity(opacity);
}
@ReactProp(name = "draggable")
public void setDraggable(AMapMarker marker, boolean draggable) {
marker.setDraggable(draggable);
}
@ReactProp(name = "image")
public void setImage(AMapMarker marker, String image) {
marker.setImage(image);
}
}
package cn.qiuxiang.react.amap3d;
import android.view.View;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.LatLng;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import java.util.Map;
class AMapViewManager extends SimpleViewManager<AMapView> {
class AMapViewManager extends ViewGroupManager<AMapView> {
private final Map<String, Integer> MAP_TYPES = MapBuilder.of(
"standard", AMap.MAP_TYPE_NORMAL,
"satellite", AMap.MAP_TYPE_SATELLITE,
......@@ -25,6 +26,14 @@ class AMapViewManager extends SimpleViewManager<AMapView> {
return "AMapView";
}
@Override
public void addView(AMapView mapView, View child, int index) {
if (child instanceof AMapMarker) {
AMapMarker marker = (AMapMarker) child;
marker.addToMap(mapView.map);
}
}
@Override
protected AMapView createViewInstance(ThemedReactContext reactContext) {
return new AMapView(reactContext);
......
import React, {PropTypes, Component} from 'react'
import {requireNativeComponent, View} from 'react-native'
import Marker from './Marker'
const CoordinateProType = PropTypes.shape({
const CoordinatePropType = PropTypes.shape({
latitude: PropTypes.number.isRequired,
longitude: PropTypes.number.isRequired,
})
......@@ -88,7 +89,7 @@ class MapView extends Component {
/**
* 设置中心坐标
*/
coordinate: CoordinateProType,
coordinate: CoordinatePropType,
/**
* 设置倾斜角度,取值范围 [0, 60]
......@@ -119,10 +120,11 @@ class MapView extends Component {
render() {
return <AMapView {...this.props}/>
}
static Marker = Marker
}
AMapView = requireNativeComponent('AMapView', MapView)
export default MapView
export {MapView}
export {MapView, Marker}
import React, {PropTypes, Component} from 'react'
import {requireNativeComponent, View} from 'react-native'
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'
import merge from 'merge'
import {CoordinatePropType} from './PropTypes'
class Marker extends Component {
static propTypes = {
...View.propTypes,
/**
* 坐标
*/
coordinate: CoordinatePropType.isRequired,
/**
* 标题
*/
title: PropTypes.string,
/**
* 描述
*/
description: PropTypes.string,
/**
* 自定义图片
*/
image: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]),
/**
* 透明度
*/
opacity: PropTypes.number,
/**
* 是否可拖拽
*/
draggable: PropTypes.bool,
/**
* 是否平贴地图
*/
flat: PropTypes.bool,
/**
* 层级
*/
zIndex: PropTypes.number,
}
render() {
if (this.props.image) {
const source = resolveAssetSource(this.props.image)
return <AMapMarker {...this.props} image={source.uri}/>
} else {
return <AMapMarker {...this.props}/>
}
}
}
AMapMarker = requireNativeComponent('AMapMarker', Marker)
export default Marker
import {PropTypes} from 'react'
const CoordinatePropType = PropTypes.shape({
latitude: PropTypes.number.isRequired,
longitude: PropTypes.number.isRequired,
})
export {CoordinatePropType}
{
"name": "Example",
"displayName": "AMap3D Examples"
}
\ No newline at end of file
{
"name": "Example",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"run-android": "node node_modules/react-native/local-cli/cli.js run-android",
"run-ios": "node node_modules/react-native/local-cli/cli.js run-ios --device",
"test": "jest"
},
"dependencies": {
......
......@@ -5,6 +5,7 @@ import Layers from './layers'
import Indoor from './indoor'
import Controls from './controls'
import Gestures from './gestures'
import Marker from './marker'
export default StackNavigator({
Examples: {screen: Examples},
......@@ -13,4 +14,5 @@ export default StackNavigator({
Indoor: {screen: Indoor},
Controls: {screen: Controls},
Gestures: {screen: Gestures},
Marker: {screen: Marker},
})
......@@ -21,17 +21,27 @@ export default class Examples extends Component {
}
render() {
return <ScrollView>
{this._renderItem('地图模式', 'MapTypes')}
{this._renderItem('图层功能', 'Layers')}
{this._renderItem('室内地图', 'Indoor')}
{this._renderItem('地图控件', 'Controls')}
{this._renderItem('手势交互', 'Gestures')}
return <ScrollView contentContainerStyle={styles.scrollView}>
<View style={styles.group}>
{this._renderItem('地图模式', 'MapTypes')}
{this._renderItem('图层功能', 'Layers')}
{this._renderItem('室内地图', 'Indoor')}
{this._renderItem('地图控件', 'Controls')}
{this._renderItem('手势交互', 'Gestures')}
</View>
<View style={styles.group}>
{this._renderItem('添加标记', 'Marker')}
</View>
</ScrollView>
}
}
const styles = StyleSheet.create({
group: {
marginTop: 15,
borderTopWidth: StyleSheet.hairlineWidth,
borderTopColor: '#ddd',
},
item: {
padding: 15,
backgroundColor: '#fff',
......
import React, {Component} from 'react'
import {StyleSheet} from 'react-native'
import {MapView, Marker} from 'react-native-amap3d'
export default class MarkerComponent extends Component {
static navigationOptions = {
title: '添加标记',
}
render() {
return <MapView style={StyleSheet.absoluteFill}>
<Marker draggable title='这是一个可拖拽的 Marker' coordinate={{
latitude: 39.806901,
longitude: 116.397972,
}}/>
<Marker image={require('../images/marker.png')} title='自定义图标' coordinate={{
latitude: 39.906901,
longitude: 116.397972,
}}/>
</MapView>
}
}
......@@ -2,22 +2,19 @@
"name": "react-native-amap3d",
"version": "0.0.1",
"description": "AMap3D component for react-native",
"main": "index.js",
"main": "components/MapView.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"react-native",
"amap"
"amap",
"maps"
],
"author": "Qiu Xiang <i@7c00.cc>",
"license": "MIT",
"peerDependencies": {
"react": ">=15.4.0",
"react-native": ">=0.40"
},
"devDependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.44.0"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment