Commit 1a607f69 authored by Qiu Xiang's avatar Qiu Xiang

实现自定义信息窗口

parent 0164651f
......@@ -44,6 +44,7 @@ public class AMapMarker extends ReactViewGroup {
COLORS.put("HUE_YELLOW", BitmapDescriptorFactory.HUE_YELLOW);
}
private ReactViewGroup infoWindow;
private Marker marker;
private LatLng position;
private String title = "";
......@@ -175,4 +176,16 @@ public class AMapMarker extends ReactViewGroup {
}
}
}
public ReactViewGroup getInfoWindow() {
return infoWindow;
}
public void setInfoWindow(ReactViewGroup view) {
infoWindow = view;
}
public void setInfoWindowLayout(int width, int height) {
infoWindow.setLayoutParams(new ReactViewGroup.LayoutParams(width, height));
}
}
package cn.qiuxiang.react.amap3d;
import android.view.View;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
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 com.facebook.react.views.view.ReactViewGroup;
import java.util.HashMap;
import java.util.Map;
class AMapMarkerManager extends SimpleViewManager<AMapMarker> {
class AMapMarkerManager extends ViewGroupManager<AMapMarker> {
@Override
public String getName() {
return "AMapMarker";
......@@ -20,6 +23,11 @@ class AMapMarkerManager extends SimpleViewManager<AMapMarker> {
return new AMapMarker(reactContext);
}
@Override
public void addView(AMapMarker marker, View view, int index) {
marker.setInfoWindow((ReactViewGroup) view);
}
@Override
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
HashMap<String, Object> map = new HashMap<>();
......@@ -70,4 +78,17 @@ class AMapMarkerManager extends SimpleViewManager<AMapMarker> {
public void setImage(AMapMarker marker, String image) {
marker.setImage(image);
}
// 对于 infoWindow,必须手动设置 layoutParams 才能正确显示,
// 但我在 Android 端没有找到监听 infoWindow onLayout 的方法,
// 我的解决办法是在 js 端监听 onLayout,并反馈到这里。
//
// PS.
// react-native-maps 的解决方法是 LayoutShadowNode,详见:
// https://github.com/airbnb/react-native-maps/blob/master/lib/android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java
// 这里暂做保留。
@ReactProp(name = "infoWindowLayout")
public void setInfoWindowLayout(AMapMarker marker, ReadableMap layout) {
marker.setInfoWindowLayout(layout.getInt("width"), layout.getInt("height"));
}
}
......@@ -2,6 +2,7 @@ package cn.qiuxiang.react.amap3d;
import android.annotation.SuppressLint;
import android.location.Location;
import android.view.View;
import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
......@@ -109,6 +110,18 @@ public class AMapView extends MapView {
markers.get(marker.getId()).sendEvent("onInfoWindowClick", Arguments.createMap());
}
});
map.setInfoWindowAdapter(new AMap.InfoWindowAdapter() {
@Override
public View getInfoWindow(Marker marker) {
return markers.get(marker.getId()).getInfoWindow();
}
@Override
public View getInfoContents(Marker marker) {
return null;
}
});
}
public void addMarker(AMapMarker marker) {
......
import React, {PropTypes, Component} from 'react'
import {requireNativeComponent, View} from 'react-native'
import {requireNativeComponent, View, PixelRatio} from 'react-native'
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'
import {CoordinatePropType} from './PropTypes'
......@@ -60,10 +60,12 @@ class Marker extends Component {
onDragStart: React.PropTypes.func,
onDrag: React.PropTypes.func,
onDragEnd: React.PropTypes.func,
onCalloutPress: React.PropTypes.func,
onInfoWindowPress: React.PropTypes.func,
}
_eventHandler(name) {
state = {}
_handle(name) {
return event => {
if (this.props[name]) {
this.props[name](event)
......@@ -71,21 +73,42 @@ class Marker extends Component {
}
}
_handleLayout(calloutLayout) {
this.setState({infoWindowLayout: {
width: PixelRatio.getPixelSizeForLayoutSize(calloutLayout.width),
height: PixelRatio.getPixelSizeForLayoutSize(calloutLayout.height),
}})
}
render() {
const props = {
...this.props,
onMarkerClick: this._eventHandler('onPress'),
onMarkerDragStart: this._eventHandler('onDragStart'),
onMarkerDrag: this._eventHandler('onDrag'),
onMarkerDragEnd: this._eventHandler('onDragEnd'),
infoWindowLayout: this.state.infoWindowLayout,
onMarkerClick: this._handle('onPress'),
onMarkerDragStart: this._handle('onDragStart'),
onMarkerDrag: this._handle('onDrag'),
onMarkerDragEnd: this._handle('onDragEnd'),
}
if (typeof props.image === 'number') {
props.image = resolveAssetSource(this.props.image).uri
}
if (props.children) {
props.children = <View
{...props.children.props}
onLayout={event => this._handleLayout(event.nativeEvent.layout)}
collapsable={false}/>
}
return <AMapMarker {...props}/>
}
}
AMapMarker = requireNativeComponent('AMapMarker', Marker)
AMapMarker = requireNativeComponent('AMapMarker', Marker, {
nativeOnly: {
infoWindowLayout: true,
},
})
export default Marker
import React, {Component} from 'react'
import {StyleSheet, Alert} from 'react-native'
import {StyleSheet, Alert, Text, View} from 'react-native'
import {MapView, Marker} from 'react-native-amap3d'
export default class MarkerComponent extends Component {
......@@ -12,23 +12,27 @@ export default class MarkerComponent extends Component {
<Marker
title='一个可拖拽的 Marker'
draggable
selected
onDragEnd={({nativeEvent}) =>
Alert.alert(`新坐标:${nativeEvent.latitude}, ${nativeEvent.longitude}`)}
onCalloutPress={() => Alert.alert('Callout Press')}
onInfoWindowPress={() => Alert.alert('信息窗口点击事件')}
coordinate={{
latitude: 39.806901,
longitude: 116.397972,
}}
/>
<Marker
selected
image='HUE_RED'
title='一个红色的 Marker'
infoWindowWidth={100}
coordinate={{
latitude: 39.806901,
longitude: 116.297972,
}}
/>
}}>
<View style={styles.customInfoWindow}>
<Text>一个自定义的信息窗口</Text>
</View>
</Marker>
<Marker
image={require('../images/marker.png')}
title='自定义图片'
......@@ -40,3 +44,15 @@ export default class MarkerComponent extends Component {
</MapView>
}
}
const styles = StyleSheet.create({
customInfoWindow: {
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff',
width: 100,
padding: 10,
borderRadius: 10,
elevation: 4,
},
})
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