【问题标题】:Fit map view to markers react native maps with Hooks, Function使地图视图适合标记与 Hooks、Function 反应原生地图
【发布时间】:2026-01-02 07:15:01
【问题描述】:

所以我有地图视图:

import * as React from 'react';
import {
    StyleSheet,
    View,
    Text,
    ScrollView,
    Animated,
    Dimensions,
    Image,
} from "react-native";
import MapView, {Callout, Marker, PROVIDER_GOOGLE} from "react-native-maps";
import * as Location from 'expo-location';
QueryResult from '../../assets/Data.json'; //JSON FILE in desc
import {AppLoading} from "expo";

const styles = StyleSheet.create({
    page: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#F5FCFF"
    },
    container: {
        flex:1,
        backgroundColor: "tomato"
    },
    map: {
        flex: 1
    },
    bubble:{
        backgroundColor: Colors.WHITE1,
        borderRadius: 20,
        flexDirection: "column",
    },
    name:{

    },
    icon:{
        width: 30,
        height:30,
    },
});

const { width, height } = Dimensions.get("window");

function GoogleMapItem() {

    const initialRegion = {
        latitude: 53.3661,
        longitude: 14.5943,
    }

    const navigation = useNavigation();
    const [location, setLocation] = React.useState(initialRegion);
    const [errorMsg, setErrorMsg] = React.useState(null);
    const mapRef = React.useRef()
    const [QueryResult, SetQueryResult] = React.useState(null);

    let iz ={
        latDelta: 0.015,
        longDelta: 0.08,
    }
    let ZOOMS = {
        _latitudeDeltaZOOM_OUT1 : iz.latDelta,
        _longitudeDeltaZOOM_OUT1: iz.longDelta,
        _latitudeDeltaZOOM_INITIAL : iz.latDelta*0.2,
        _longitudeDeltaZOOM_INITIAL: iz.longDelta*0.2,
        _latitudeDeltaZOOM_IN1 :  iz.latDelta*0.1,
        _longitudeDeltaZOOM_IN1:  iz.longDelta*0.1,
    }

    React.useEffect(() => {
        (async () => {
            let { status } = await Location.requestPermissionsAsync();
            if (status !== 'granted') {
                setErrorMsg('Permission to access location was denied');
            }

            let location = await Location.getCurrentPositionAsync({});
            const {longitude, latitude} = location.coords
            setLocation({
                ...location,
                longitude: longitude,
                latitude: latitude,
            })
        })();
    }, []);

        return(
            <View style={styles.map}>
                <MapView style={styles.map}
                         provider={PROVIDER_GOOGLE}
                         loadingEnabled={true}
                         region={{
                             latitude: location.latitude,
                             longitude: location.longitude,
                             latitudeDelta:  ZOOMS._latitudeDeltaZOOM_OUT1,
                             longitudeDelta: ZOOMS._latitudeDeltaZOOM_OUT1,
                         }}
                         showsUserLocation
                         followsUserLocation
                         userLocationUpdateInterval
                         ref={mapRef}

                >
                    {QueryResult.results.map((element,index)=>
                        <Marker key={index} identifier={element.place_id} coordinate={{
                            latitude: element.geometry.location.lat,
                            longitude: element.geometry.location.lng,
                        }}
                        >
                            <View>
                                <Image source={{uri: element.icon}} style={{width:25,height:25,}}></Image>
                            </View>
                        </Marker>
                    )}
                </MapView>
            </View>

        )

}




export default React.memo(GoogleMapItem)

并缩短为两个条目的json文件:

{
   "results" : [
      {
         "business_status" : "OPERATIONAL",
         "geometry" : {
            "location" : {
               "lat" : 53.368006,
               "lng" : 14.6198066
            },
         },
         "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/generic_recreational-71.png",
         "name" : "Park Leśny Zdroje",
         "place_id" : "ChIJ7adAEfunAEcRUlmcp_1ReY8",
      },
      {
         "business_status" : "OPERATIONAL",
         "geometry" : {
            "location" : {
               "lat" : 53.3789812,
               "lng" : 14.6186994
            },
         },
         "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/generic_business-71.png",
         "name" : "Usługi Ogrodnicze Szczecin Miłorząb M.",
         "place_id" : "ChIJxwSQa_SnAEcRsgtHuw_eeuE",
      },
   ],
   "status" : "OK"
}

这个视图正在渲染查询中的标记(带有餐馆或其他对象的视图) 我想适合 mapview 以查看所有可能的标记。

这可以通过钩子实现吗? (几乎所有互联网上的解决方案都使用: {mapRef=&gt; this.mapRef= mapRef} 所以需要类组件。

尝试了不同的方法,例如:

OnMapReady or onLayout={ mapRef.current.fitToSuppliedMarkers(markerArray)}
OnMapReady or onLayout={ mapRef.current.fitToElements(true)}

将所有标记 Lat、Lng 添加到数组中,然后:

OnMapReady or onLayout={ mapRef.current.fitToCoordinates(markerArrayLatLng}

也尝试过在 useEffect 中使用这些方法,但它根本看不到 mapRef(mapRef 未定义)。

但是什么也没发生,我认为错误是在第一次初始渲染时,这些方法看不到要映射的引用。 因为当我使用按钮调用方法时,它工作正常。

<Button title={"test"} onPress={mapRef.current.fitToElements(true)}/>

这在带有钩子的函数中是否可行,或者我需要将整个函数重新排列为类组件?

抱歉,我的语言有错误。

【问题讨论】:

    标签: javascript react-native google-maps google-maps-markers react-native-maps


    【解决方案1】:

    followUserLocation 正在自动缩放到用户位置(速度如此之快),以至于 fitToElements 和其他人不起作用(它们起作用但会立即缩放)。 所以我设置了关注超时。

    【讨论】: