首页 > 解决方案 > 询问权限时无法将地图视图中的初始区域设置为当前位置

问题描述

我试图让地图在屏幕启动时显示当前位置。当已授予位置权限时,该代码运行良好。当请求权限时,地图会在更新状态之前从状态中获取默认值。我在我的应用程序中使用 redux。

LocationScreen.js

        Geolocation.getCurrentPosition(position => {
            const latitude = position.coords.latitude;
            const longitude = position.coords.longitude;
            this.props.dispatch({type: 'UPDATE_LOCATION', location:{latitude:latitude,longitude:longitude}})
        });
    }


    render() {    
        const location = this.props.location;
        return (
            <View style={styles.MainContainer}>
                <StatusBar backgroundColor="#ffffff" barStyle="dark-content" />
                <View pointerEvents="none" style={{zIndex:99 ,position: 'absolute', top: 0, bottom: 0, left: 0, right: 0, alignItems: 'center', justifyContent: 'center', backgroundColor: 'transparent'}}>
                    <Image pointerEvents="none" style={{height:59,width:40, marginBottom:60}} source={require('../../../assets/marker1.png')}/>
                </View>
                <MapView
                    provider={PROVIDER_GOOGLE} // remove if not using Google Maps
                    style={{width:'100%',height:'100%'}}
                    initialRegion={{
                        latitude: location.latitude,
                        longitude: location.longitude,
                        latitudeDelta: 0.00005,
                        longitudeDelta: 0.0021,
                    }}
                    onRegionChange={(region) => {
                        this.props.dispatch({type: 'UPDATE_LOCATION', location:{latitude:region.latitude,longitude:region.longitude} });
                    }}
                >
                    {/* <Marker
                        coordinate={{latitude:location.latitude,longitude:location.longitude}} 
                    /> */}
                </MapView>
                <View style={styles.bottomView}>
                    <TouchableOpacity style={{ height: 40, width:'80%', backgroundColor:'#00665c', justifyContent:'center', alignItems:'center', marginHorizontal:'10%', marginBottom:20 }}
                        onPress={() => this.props.navigation.navigate('Details_one_reg')}
                    >
                        <Text style={{color:'white'}}>Next</Text>
                    </TouchableOpacity>
                    <Text style={{color:'gray',marginLeft:30,marginBottom:25}}>Drag and drop pin on the location of the Shop</Text>
                    <Text style={{fontWeight:'bold',fontSize:16, marginLeft:30, marginBottom:4}}>Location</Text>
                </View>
            </View>
        );
    }
}

const mapStateToProps = (state) =>{
    return {
      location : state.location, 
    }
}


export default connect(mapStateToProps)(LocationScreen);

状态树

export const stateTree = {
    auth:{
        mobile_no:7397440807,
        otp:100000,
    },
    location:{
        latitude:0,
        longitude:0,
    },
    inventory : [

标签: react-nativereduxreact-native-maps

解决方案


为了完成这项工作,我必须将 MapView 的 onRegionChangeComplete 处理程序与 region 属性结合使用。组件的构造函数请求位置权限,然后获取当前位置并设置状态。MapView 有一个与构造函数中设置的状态相关联的属性。您可能可以简化这一点。

重要的是要注意 onChangeRegion 是一个在地图移动时连续触发的事件,因此在组件首次加载时不会被调用。onChangeRegionComplete 在地图稳定时触发,并在组件加载时触发。

interface ExampleProps {

}

interface ExampleState {
    region: any
}

export class ExampleComponent extends Component<ExampleProps, ExampleState> {

    constructor(props: ExampleProps) {
        super(props);

        if (Platform.OS === "android") {
            this.requestLocationPermission();
        }

        this.state = {
            region: {
                longitude: 0,
                latitude: 0,
                longitudeDelta: 0.004,
                latitudeDelta: 0.009
            }
        };

        Geolocation.getCurrentPosition(
            (position) => {
                console.log(position);
                this.setState({
                    region: {
                        longitude: position.coords.longitude,
                        latitude: position.coords.latitude,
                        longitudeDelta: 0.004,
                        latitudeDelta: 0.009
                    }
                });
            },
            (error) => {
                // See error code charts below.
                console.log(error.code, error.message);
                throw error;
            },
            { 
                showLocationDialog: true,
                forceRequestLocation: true, 
                enableHighAccuracy: true, 
                timeout: 15000, 
                maximumAge: 10000 
            }
        );

    }

    async requestLocationPermission() {
        try {
          const granted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
            {
              title: "Example App",
              message: "Example App access to your location "
            }
          );
          if (granted === PermissionsAndroid.RESULTS.GRANTED) {
            console.log("You can use the location");
            alert("You can use the location");
          } else {
            console.log("location permission denied");
            alert("Location permission denied");
          }
        } catch (err) {
          console.warn(err);
        }
    }

    render() {
      return (
        <View style={styles.container}>
            <MapView
                provider = { PROVIDER_GOOGLE }
                style = {styles.map}
                region = {this.state.region} 
                onRegionChange={ region => {
                    //console.log("Region Changed");
                    //this.setState({region});
                 } }
                onRegionChangeComplete={ region => {
                    console.log("Region change complete");
                    this.setState({region});
                 } }
                showsUserLocation={ true } >
            </MapView>
        </View>
      );
    }
  }

  const styles = StyleSheet.create({
      container: {
          flex: 1
      },
      map: {
          flex: 1
      }
  })

推荐阅读