import React from 'react';
import { StyleSheet, View, Dimensions, Platform, SafeAreaView } from 'react-native';
import MapView, { Marker, AnimatedRegion } from 'react-native-maps';
import PubNubReact from 'pubnub-react';
const { width, height } = Dimensions.get('window');
const ASPECT_RATIO = width / height;
const LATITUDE = 37.78825;
const LONGITUDE = -122.4324;
const LATITUDE_DELTA = 0.0922;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
console.disableYellowBox = true;
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
latitude: LATITUDE,
longitude: LONGITUDE,
coordinate: new AnimatedRegion({
latitude: null,
longitude: null,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}),
};
// Replace "X" with your PubNub Keys
this.pubnub = new PubNubReact({
publishKey: 'X',
subscribeKey: 'X',
});
this.pubnub.init(this);
}
// code to receive messages sent in a channel
componentDidMount() {
this.subscribeToPubNub();
}
subscribeToPubNub = () => {
this.pubnub.subscribe({
channels: ['location'],
withPresence: true,
});
this.pubnub.getMessage('location', msg => {
const { coordinate } = this.state;
const { latitude, longitude } = msg.message;
const newCoordinate = { latitude, longitude };
if (Platform.OS === 'android') {
if (this.marker) {
this.marker._component.animateMarkerToCoordinate(newCoordinate, 500);
}
} else {
coordinate.timing(newCoordinate).start();
}
this.setState({
latitude,
longitude,
});
});
};
getMapRegion = () => ({
latitude: this.state.latitude,
longitude: this.state.longitude,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
});
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<MapView
style={styles.map}
showUserLocation
followUserLocation
loadingEnabled
ref={c => (this.mapView = c)}
region={this.state.latitude ? this.getMapRegion() : null}
>
<Marker.Animated
ref={marker => {
this.marker = marker;
}}
coordinate={this.state.coordinate}
/>
</MapView>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
justifyContent: 'flex-end',
alignItems: 'center',
},
map: {
...StyleSheet.absoluteFillObject,
},
});
export default App;
我在我的 React Native 代码中收到"无法读取未定义的属性'animateMarkerToCoordinate'"的错误。我正在安卓上开发位置跟踪应用程序。从另一个应用程序中提取LAT和LONG,并且想要动画在谷歌地图上。我在其他一些网站上读到,animateMarkerToCoordinate 在 Android 版 React Native 中不起作用。是真的吗?如果不是,这个问题的解决方案是什么?
这个问题出现在 React 原生0.63.+
版本中。根据react-native-maps
的官方文件
const duration = 500
if (this.props.coordinate !== nextProps.coordinate) {
if (Platform.OS === 'android') {
if (this.marker) {
this.marker._component.animateMarkerToCoordinate(
nextProps.coordinate,
duration
);
}
} else {
this.state.coordinate.timing({
...nextProps.coordinate,
duration
}).start();
}
}
但这不适用于最新的 React-native 版本。 只需在animateMarkerToCoordinate
之前删除_component
,它就可以正常工作。
const duration = 500
if (this.props.coordinate !== nextProps.coordinate) {
if (Platform.OS === 'android') {
if (this.marker) {
this.marker.animateMarkerToCoordinate(
nextProps.coordinate,
duration
);
}
} else {
this.state.coordinate.timing({
...nextProps.coordinate,
duration
}).start();
}
}
在当前版本的 React Native 和 PubNub (4.31+( 中,使用getMessage
方法可能无法正确获取消息,因此"消息"显示为undefined
。
因此,如果有人遇到此问题,只需按照各自的文档使用addListener
而不是getMessage
。
我花了几天时间尝试运行相同的代码,我希望我可以帮助其他人。
基于这个 GitHub 答案:https://github.com/react-native-community/react-native-maps/issues/2195#issuecomment-424246731 最好只使用coordinate.timing(newCoordinate).start();
代码。
Invariant Violation: [37,"AIRMapMarker",481,{"coordinate":{"latitude":37.78825,"longitude":-122.4324,"latitudeDelta":"<<NaN>>","longitudeDelta":"<<NaN>>"},"position":"absolute","backgroundColor":0}]
导致此失败是因为newCoordinate
缺少latitudeDelta
和longitudeDelta
,因此最终代码应如下所示:
this.pubnub.getMessage('location', msg => {
const { coordinate } = this.state;
const { latitude, longitude } = msg.message;
const newCoordinate = {
latitude,
longitude,
latitudeDelta = LATITUDE_DELTA,
longitudeDelta = LONGITUDE_DELTA
};
coordinate.timing(newCoordinate).start();
this.setState({
latitude,
longitude,
});
});
使用 try catch。它不会崩溃
if (this.marker && this.mounted) {
setTimeout(() => {
try {
this.marker.animateMarkerToCoordinate(
coordinate,
duration
)
} catch (error) {
console.log(error)
}
}, 100);
// this.marker._component.animateMarkerToCoordinate(
// coordinate,
// duration
// );
}
this.marker.animateMarkerToCoordinate 使用 this 而不是 this.marker._component.animateMarkerToCoordinate