Reputation: 966
I am attempting to run a map on my app. This code works perfectly on iOS, but throws the above error on Android alone. I have tried troubleshooting with current online resources, but they are either older, or they are mainly for "class" format, while my code is written using hooks.
The full error is:
Error using newLatLngBounds (LatLngBounds, int): Map size can't be 0. Most likely, layout has not yet occured for the map view. Either eait until layout has occurred or use newLatLngBounds(LatLngBounds, int, int, int) which allows you to specify the map's dimensions.
Below is my code,
import React, { useState, useEffect, Component }from "react";
import {ActivityIndicator, Alert, BackHandler, Button, Dimensions, Platform, SafeAreaView, StyleSheet, Text, TouchableOpacity, ScrollView, View,} from "react-native";
import MapView, { Marker, Callout, Polyline, PROVIDER_GOOGLE, Heatmap } from "react-native-maps";
import Modal from 'react-native-modal';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
import * as Localization from 'expo-localization'
import { useFocusEffect } from '@react-navigation/native'
import { Permissions , Request } from 'expo-permissions'
import * as Location from 'expo-location'
function Locator({navigation, route}) {
const [user_latitude, setUserLatitude] = useState(0)
const [user_longitude, setUserLongitude] = useState(0)
const [position_error, setPositionError] = useState(null)
const [ isLoading, setIsLoading ] = useState(true)
const [ location, setLocation ] = useState(null);
const renderLoading = () => {
if (isLoading) {
return (
<View style = {{justifyContent: 'center', backgroundColor: '#d3d3d3', height: height, width: width}}>
<ActivityIndicator
color = 'black'
size = 'large'
animated = {false}
/>
<Text style = { styles.text }>Locating</Text>
</View>
);
}else {
return null;
}
}
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', () => true)
return () =>
BackHandler.removeEventListener('hardwareBackPress', () => true)
},
[]
)
useFocusEffect(
React.useCallback(()=> {
let isActive = true;
const fetchGeoPosition = () => {
navigator.geolocation.getCurrentPosition(
position => {
if (isActive){
setUserLatitude(position.coords.latitude);
setUserLongitude(position.coords.longitude);
setPositionError(null);
console.log('Location Accessed')
}
setIsLoading(false)
},
error => isActive && setPositionError(error.message),
{enableHighAccuracy: true, timeout: 0, maximumAge: 1000}
);
}
const permission_get = async () => {
if (Platform.OS === 'android' && !Constants.isDevice) {
setErrorMsg(
'Oops, this will not work on Snack in an Android emulator. Try it on your device!'
);
return;
}
let { status } = await Location.requestPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
console.log('Not permitted')
return;
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
}
permission_get()
fetchGeoPosition()
return () =>{
isActive = false
console.log('Location Severed')
}
},
[],
),
)
return(
<View style = {styles.container}>
{(renderLoading())}
<View style = {styles.header}>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
region= {{
latitude: user_latitude,
longitude: user_longitude,
latitudeDelta: 0.1451,
longitudeDelta: 0.1451
}}>
<Marker
coordinate={
{latitude: user_latitude,
longitude: user_longitude,
error: position_error,
}}
>
</Marker>
</MapView>
</View>
<View style = {styles.footer}>
<View style = {styles.buttonView}>
<TouchableOpacity
onPress= { null }
style = {styles.signIn}
>
<Text style = {styles.buttonText}>Cancel</Text>
</TouchableOpacity>
</View>
<View style = {styles.buttonView}>
<TouchableOpacity
onPress = { null }
style = {styles.signIn}
>
<Text style = {styles.buttonText}>Continue</Text>
</TouchableOpacity>
</View>
</View>
</View>
)
}
export {Locator};
const {height}= Dimensions.get("screen");
const { width } = Dimensions.get("screen")
const styles = StyleSheet.create({
container: {
flex: 100,
flexDirection: 'column',
},
header:{
flex: 90,
width: width,
},
map: {
...StyleSheet.absoluteFillObject,
},
middle: {
width: '100%',
flex: 15,
borderColor: '#d3d3d3',
borderWidth: 5,
backgroundColor: '#d3d3d3',
},
footer: {
width: width,
flex: 10,
backgroundColor: '#d3d3d3',
justifyContent: 'space-evenly',
flexDirection: 'row',
},
text: {
textAlign: 'center',
color: 'black',
},
button: {
fontSize: height*0.03,
width: width*0.45,
textAlign: 'center',
height: height*0.05,
color: '#d3d3d3',
fontWeight: 'bold',
borderRadius: 20,
justifyContent: 'center'
},
buttonText:{
textAlign: 'center',
fontWeight: 'bold',
color: 'black',
fontSize: height*0.025
},
textSign: {
color: '#fff',
fontWeight: 'bold',
fontSize: 20,
width: '100%',
paddingTop: 20,
textAlign: 'center',
},
modal: {
backgroundColor: '#d3d3d3',
alignItems: 'center',
width: '100%',
height: '20%',
paddingRight: 20,
borderRadius: 10,
color: 'black',
},
searchBox:{
top: 0,
position: 'absolute',
width: width,
},
signIn: {
width: width*0.45,
height: height*0.055,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
flexDirection: 'row',
fontSize: height*0.02,
borderColor: 'black',
backgroundColor: '#fff',
marginTop: height*0.01,
},
buttonView:{
alignItems: 'center',
marginTop: height*0.001,
},
});
Upvotes: 2
Views: 1494
Reputation: 966
While
map: {
...StyleSheet.absoluteFillObject,
},
is an acceptable format for iOS, Android requires you to specify the Map's dimensions. The error above can be fixed by doing something as simple as:
map: {
...StyleSheet.absoluteFillObject,
height: height*0.8
},
Upvotes: 1