React-native-maps和Geolocation无法正确获取位置

问题描述

我对学习React Native还是一个新手,很感谢我的代码可以提供的任何帮助。我目前正在研究教程,已经被困了几个小时。希望这是足够的信息,以获得一些帮助。预先感谢!

我的目标

我正在尝试按此顺序做三件事:

  1. 获取用户的当前位置
  2. 从API中获取商品数据(以下概述的示例)。应该注意的是,最终获取内容将取决于用户的当前位置。
  3. 解析项目数据以创建标记和唯一的类别列表,然后将其放置在地图上,并以用户当前的位置为中心。

我希望能够观察用户的位置并相应地移动和更新地图。在所有标记都到位之前,我也不想显示地图。

这是我的react版本:react-native-cli:2.0.1 react-native:0.63.2

我的错误

我同时使用Android Studio模拟器和Xcode模拟器,并且目前遇到以下问题:

  1. Xcode上的iOS模拟器第一次呈现良好效果,但是在随后的刷新中,我发现5个标记中的一两个缺失。
  2. 在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 (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...