问题描述
我对学习React Native还是一个新手,很感谢我的代码可以提供的任何帮助。我目前正在研究教程,已经被困了几个小时。希望这是足够的信息,以获得一些帮助。预先感谢!
我的目标
我正在尝试按此顺序做三件事:
- 获取用户的当前位置
- 从API中获取商品数据(以下概述的示例)。应该注意的是,最终获取的内容将取决于用户的当前位置。
- 解析项目数据以创建标记和唯一的类别列表,然后将其放置在地图上,并以用户当前的位置为中心。
我希望能够观察用户的位置并相应地移动和更新地图。在所有标记都到位之前,我也不想显示地图。
这是我的react版本:react-native-cli:2.0.1 react-native:0.63.2
我的错误
我同时使用Android Studio模拟器和Xcode模拟器,并且目前遇到以下问题:
- Xcode上的iOS模拟器第一次呈现良好效果,但是在随后的刷新中,我发现5个标记中的一两个缺失。
- 在Android上,地图会完美加载,然后立即重新绘制地图并以加利福尼亚州的Googleplex为中心,而不是用户当前的位置。 Emulator location is set to London,UK
我怀疑在地图渲染之前我可能会在获取物品和当前位置时遇到某些比赛情况,但是我不确定。
我的代码
//我的API响应结构
{
"id": "96845","title": "Item_title_goes_here","image": "https://someURL/image.JPG","stories": 46,"lat": some_lat_number,"lon": some_lon_number,"category": "category_name","description": "long_description"
},
//ajax.js
export default {
async fetchInitialItems() {
try {
const response = await fetch(apiHost + '/api/v1/items/');
const responseJson = await response.json();
return responseJson;
} catch (error) {
console.error(error);
}
},async fetchItemDetail(itemId) {
try {
const response = await fetch(apiHost + '/api/items/' + itemId);
const responseJson = await response.json();
return responseJson;
} catch (error) {
console.error(error);
}
},};
//ExploreScreen.js (my map component)
import React,{ Component } from 'react';
import {
View,Text,StyleSheet,Image,Animated,Dimensions,TouchableOpacity,PermissionsAndroid,ScrollView,Platform,StatusBar,} from 'react-native';
import MapView,{
PROVIDER_GOOGLE,Marker,Callout,polygon,} from 'react-native-maps';
import PropTypes from 'prop-types';
import Geolocation from '@react-native-community/geolocation';
import { mapDarkStyle,mapStandardStyle } from '../model/mapData';
import ajax from '../utils/ajax';
import MapCarousel from './MapCarousel';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Fontisto from 'react-native-vector-icons/Fontisto';
import Starrating from '../components/Starrating';
/**
|--------------------------------------------------
| Variables
|--------------------------------------------------
*/
const { width,height } = Dimensions.get('window');
const SCREEN_HEIGHT = height;
const SCREEN_WIDTH = width;
const ASPECT_RATIO = width / height;
const LATITUDE_DELTA = 0.0422;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
const darkTheme = false;
/**
|--------------------------------------------------
| Component
|--------------------------------------------------
*/
class ExploreScreen extends React.Component {
/****** Props & States ******/
state = {
region: {
latitude: 0,longitude: 0,latitudeDelta: LATITUDE_DELTA,longitudeDelta: LONGITUDE_DELTA,},items: [],markers: [],categories: [],currentMapRegion: null,};
/****** Functions ******/
///when carousel item selected
onCarouselItemSelected() {
alert('carousel item selected');
}
//when the carousel in scrolled
onCarouselIndexChange(itemID) {
const item = this.state.items.find(item => item.id == itemID);
const marker = this.state.markers.find(marker => marker.id == itemID);
const coordinates = { lat: item.lat,lon: item.lon };
this.goToLocation(coordinates);
}
//get current position
getLocation(that) {
Geolocation.getCurrentPosition(
//get the current location
position => {
const region = {
latitude: parseFloat(position.coords.latitude),longitude: parseFloat(position.coords.longitude),};
that.setState({ region });
},error => alert(error.message),{ enableHighAccuracy: true,timeout: 20000 },);
//get location on location change
that.watchID = Geolocation.watchPosition(position => {
const currentRegion = {
latitude: position.coords.latitude,longitude: position.coords.longitude,};
this.setState({ region: currentRegion });
});
}
//move map to a lat/lon
goToLocation(coordinates) {
if (this.map) {
this.map.animatetoRegion({
latitude: coordinates.lat,longitude: coordinates.lon,});
}
}
//when the region changes for the map
onRegionChangeComplete(region) {
//I dont kNow what to do here
}
//move map to center of current location
gottoCenter() {
if (this.map) {
this.map.animatetoRegion({
latitude: this.state.region.latitude,longitude: this.state.region.longitude,});
}
}
//map the categories store in the state
mapCategories = () => {
const uniqueCategories = [];
this.state.items.map(item => {
if (uniqueCategories.indexOf(item.category) === -1) {
uniqueCategories.push(item.category);
}
});
this.setState({ categories: uniqueCategories });
};
//map the items to markers and store in the state
mapMarkers = () => {
const markers = this.state.items.map(item => (
<Marker
key={item.id}
coordinate={{ latitude: item.lat,longitude: item.lon }}
image={require('../assets/map_marker.png')}
tracksViewChanges={false}
title={item.title}
description={item.description}
/>
));
this.setState({ markers: markers });
};
/****** Lifecycle Functions ******/
async componentDidMount() {
var that = this;
//Checking for the permission just after component loaded
if (Platform.OS === 'ios') {
//for ios
this.getLocation(that);
} else {
//for android
async function requestLocationPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,{
title: 'Location Access required',message: 'This App needs to Access your location',);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
//To Check,If Permission is granted
that.getLocation(that);
} else {
alert('Permission Denied');
}
} catch (err) {
alert('err',err);
console.warn(err);
}
}
requestLocationPermission();
}
//get location on location change
that.watchID = Geolocation.watchPosition(position => {
const currentRegion = {
latitude: parseFloat(position.coords.latitude),};
this.setState({ region: currentRegion });
});
console.log(this.state.region);
const items = await ajax.fetchInitialItems();
this.setState({ items });
this.mapMarkers();
this.mapCategories();
}
componentwillUnmount = () => {
Geolocation.clearWatch(this.watchID);
};
render() {
const lat = this.state.region.latitude;
const lon = this.state.region.longitude;
if (this.state.items && lat && lon) {
return (
<View>
<MapView
ref={map => {
this.map = map;
}}
onRegionChangeComplete={this.onRegionChangeComplete.bind(this)}
toolbarEnabled={false}
showsMyLocationButton={false}
provider={PROVIDER_GOOGLE}
style={styles.map}
customMapStyle={darkTheme ? mapDarkStyle : mapStandardStyle}
showsUserLocation={true}
followsUserLocation={true}
region={this.state.region}>
{this.state.markers}
</MapView>
{/* center button */}
<TouchableOpacity
onPress={this.gottoCenter.bind(this)}
style={styles.centerButtonContainer}>
<Ionicons name="md-locate" size={20} />
</TouchableOpacity>
<View style={styles.carousel}>
<MapCarousel
data={this.state.items}
onPressItem={() => {
this.onCarouselItemSelected.bind(this);
}}
onUpdateLocation={this.onCarouselIndexChange.bind(this)}
/>
</View>
</View>
);
} else {
return (
<View style={styles.container}>
<Text style={styles.header}>Loading...</Text>
</View>
);
}
}
}
/**
|--------------------------------------------------
| Styles
|--------------------------------------------------
*/
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,height: '100%',width: '100%',justifyContent: 'center',alignItems: 'center',map: {
height: '100%',carousel: {
position: 'absolute',bottom: 25,header: {
fontSize: 50,//character name
name: {
fontSize: 15,marginBottom: 5,//character image
image: {
width: 170,height: 80,//center button
centerButtonContainer: {
width: 40,height: 40,position: 'absolute',bottom: 260,right: 10,borderColor: '#191919',borderWidth: 0,borderRadius: 30,backgroundColor: '#d2d2d2',shadowColor: '#000',shadowOffset: {
width: 0,height: 9,shadowOpacity: 0.48,shadowRadius: 11.95,elevation: 18,opacity: 0.9,});
export default ExploreScreen;
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)