React Native Maps:在react-native-maps中使用自定义标记时,标记图像不显示

17

我正在使用react-native-maps,但遇到一个问题,经过很多搜索也没有得到答案,所以现在在这里提问。

我想在地图中为标记使用自定义标记,就像下面的图片:

enter image description here

  • 根据我的搜索结果,我发现需要使用自定义标记来实现标记的设计,然后我创建了一个自定义标记组件。

    import React, { Component } from "react";
    import { View } from "react-native";
    import {
    Text,
    Left,
    Right,
    Thumbnail,
    } from "native-base";
    const defaultEmployeeLogo = require("../../../assets/defualtEmployee.png");
    class CustomMarker extends Component {
    render() {
        return (
        <View style={{ flexDirection: 'row', width: 140, height: 60, 
          borderRadius: 70, backgroundColor: 'orange' }}>
            <Left>
                <Thumbnail source={defaultEmployeeLogo} />
            </Left>
            <Right>
                <Text style={{
                    color: '#fef',
                    fontSize: 13,
                    paddingBottom: 2,
                    fontFamily: 'Roboto',
                    alignItems: 'center',
                    paddingRight: 10
                }}>Mohammad</Text>
            </Right></View >);
       }
    }
    export default CustomMarker;
    

当我仅使用CustomMarker.js类时,它可以正常工作并显示图片,但是当我将其用作标记自定义视图时,它无法显示图片。

enter image description here

我不知道为什么它无法在Android中使用自定义标记渲染图像。以下是我使用地图、标记和自定义标记类的代码:

return (
  <View style={styles.map_container}>
    <MapView
      style={styles.map}
      customMapStyle={customrMapStyle}
      region={{
        latitude: this.state.region.latitude,
        longitude: this.state.region.longitude,
        latitudeDelta: 0.4,
        longitudeDelta: 0.41,
      }} >
      {
        coordinationData.map(function (marker, i) {

          let lat = marker.latLang.latitude;
          let lang = marker.latLang.longitude;
           <MapView.Marker
            key={i}
            coordinate={
              {
                latitude: lat,
                longitude: lang,
                latitudeDelta: 0.4,
                longitudeDelta: 0.41
              }
            }
            title={marker.title}
            description={marker.description}

          >
            <CustomMarker />
          </MapView.Marker>
        })}
    </MapView>
  </View>

希望能得到任何形式的帮助。

10个回答

8

使用 SVG,可以参考这个链接:https://github.com/react-native-community/react-native-svg

<Marker
    coordinate={{
        longitude: lang,
        latitude: lat,
    }}
>
    <View style={{
        flexDirection: 'row', width: 100, height: 30,
        backgroundColor: 'orange'
    }}>
        <Svg
            width={40} height={30}>
            <Image
                href={url}
                width={40}
                height={30}
            />
        </Svg>
        <View
            style={{
                flexDirection: 'column'

            }}
        >
            <Text
                style={{
                    marginLeft: 2,
                    fontSize: 9,
                    color: '#ffffff',
                    fontWeight: 'bold',
                    textDecorationLine: 'underline'
                }}
            >{marker.title}</Text>
            <Text
                style={{
                    marginLeft: 2,
                    fontSize: 9,
                    color: '#ffffff',
                    fontWeight: 'bold',
                    textDecorationLine: 'underline'
                }}
            >{marker.description}</Text>
        </View>
    </View>
</Marker>

5

我的问题现在已经解决了。

希望你的问题也能得到解决。

这是我的干净代码:

import React, {Component} from 'react';
import {ImageBackground, Text} from 'react-native';
import {Marker} from 'react-native-maps';

export default class CustomMarker extends Component {
    state = {
        initialRender: true
    }

    render() {
        return (
            <Marker
              //...
            >
                <ImageBackground
                    source={require('../assets/cluster3_mobile.png')}>

                    // *** These lines are very important ***
                    onLoad={() => this.forceUpdate()}
                    onLayout={() => this.setState({initialRender: false})}
                    key={`${this.state.initialRender}`}
                    >
                    

                    // **** This line is very very important ****
                    <Text style={{width: 0, height: 0}}>{Math.random()}</Text>

                </ImageBackground>
            </Marker>
        );
    }
}

我认为你必须给ImageBackground添加样式,至少在Android上运行时会显示这个错误。@Mahdi Bashirpour - Abdu4
不要使用native-base,测试这个直接的代码。也许是问题所在。或者在地图之外的其他地方测试组件代码,看看它是否能正常工作。@Abdu4 - Mahdi Bashirpour
如果整个东西都是从一个地图中运作的,那么很可能是与组件 native-base 相关的地图出了问题。@Abdu4 - Mahdi Bashirpour
你在安卓手机上试过你的代码了吗?@Mahdi Bashirpour - Abdu4
它成功了吗?如果是的话,您能分享一张截图以展示给我的雇主@Mahdi Bashirpour吗? - Abdu4
显示剩余2条评论

3

截至2019年10月,只要将tracksViewChanges设置为true,就可以在标记中显示图像。我使用FastImage,但一般的想法是先将tracksViewChanges设置为true,然后在图像加载完成后立即将其设置为false,以避免任何性能问题。

export const UserMapPin = props => {
  const [trackView, setTrackView] = useState(true);

  function changeTrackView() {
    setTrackView(false);
  }

  return (
    <Marker
      tracksViewChanges={trackView}
      coordinate={props.coordinates}>
      <View style={styles.imageIconContainer}>
          <FastImage
            onLoadEnd={changeTrackView}
            style={styles.someImageStyle}
            source={{
              uri: props.imageURI,
            }}
            resizeMode={FastImage.resizeMode.cover}
          />
      </View>
    </Marker>
  );
};

2

我采用了@Mahdi Bashirpour的解决方案,只是进行了升级。

如果我们从'react-native-svg'导入'Image',则其他图像将停止工作。

我的解决方案如下。

import {Image} from 'react-native';   // for other images in our render method.
import { Image as Imagesvg } from 'react-native-svg';

<Marker
   coordinate={marker.latlng}
   title={marker.title}
 >

<View style={{ height: 90, width: 90, backgroundColor: 'orange' }}>
      <Svg width={90} height={90}}>
        <Imagesvg href={marker_g} width={90} height={90} />  // Local Images
       <Imagesvg href={{uri:url}} width={90} height={90} />   //Server images
    </Svg>
</View>
</Marker>

使用 'Imagesvg' 作为标记图像。 在安卓7和8上运行正常。React Native版本为 '0.55.3'


2

我有同样的问题。

当您首次加载应用程序时,图像不会显示,但对于后续加载,此问题将得到解决并显示图像。

在图像加载后立即调用 this.forceUpdate() 即可解决问题。

const defaultEmployeeLogo = require("../../../assets/defualtEmployee.png");

<Image source={defaultEmployeeLogo} onLoad={() => this.forceUpdate()}>
    <Text style={{width:0, height:0}}>{Math.random()}</Text>
</Image>

你可以跟踪这个问题: https://github.com/react-community/react-native-maps/issues/924

我正在从本地项目中加载图像,既不是从Web服务器也不是从AsynStorage中加载。@Mahdi Bashirpour - Abdu4
不,你不能从网络上获取图像。 你的图片是本地的。const defaultEmployeeLogo = require("../../../assets/defualtEmployee.png"); - Mahdi Bashirpour
除此之外,如果我在标记(Marker)内使用图像作为标记(tag),它可以正常工作,但是由于我需要在自定义视图中使用文本和图像,因此我需要在标记中使用自定义视图。 - Abdu4
嗯,为什么对我不起作用呢?你在哪个平台上运行APP,是安卓还是iOS?@Mahdi Bashirpour - Abdu4
运行在Android平台上 @Abdu4 - Mahdi Bashirpour
显示剩余2条评论

1
这是另一个例子。
class PinMarker extends Component {
  state = {
    initialRender: true
  }
  render() {
    return (
      <MapView.Marker coordinate={coordinate}>
        <Image
          source={...}
          onLayout={() => this.setState({ initialRender: false })}
          key={`${this.state.initialRender}`}
        />
      </MapView.Marker>
    )
  }
}

1
非常感谢您的回复,但是仍然出现了相同的结果,地图加载了,但是图片没有显示。 - Abdu4
有其他的想法吗?@Mahdi Bashirpour - Abdu4
1
因为我自己也遇到了同样的问题,所以我现在正在解决它。我已经得出了很好的结果 @abdu4 - Mahdi Bashirpour

1
我曾经遇到过同样的问题,来自Github帖子
使用以下(MapView, Image)模式,首次加载时仍然会出现问题。
<MapView.Marker>
    <Image source={img_marker} />
</MapView.Marker>

因此,采用以下解决方案:关键是将当前选择的标记ID保存在Redux中。

class Map extends React.Component {
render() {
    let {region, markers , markerClick} = this.props;
    const normalMarkerImage = require('../../images/normal_marker.png');
    const selectedMarkerImage = require('../../images/selected_marker.png');
    return !isObjectEmpty(region) && !isObjectEmpty(markers) ? (
        <MapView
            style={styles.map}
            showsUserLocation={true}
            followUserLocation={true}
            zoomEnabled={true}
            region={region}
            paddingAdjustmentBehavior={'automatic'}
            showsIndoors={true}
            showsIndoorLevelPicker={false}
            showsTraffic={false}
            toolbarEnabled={false}
            loadingEnabled={true}
            showsMyLocationButton={true}>
            {markers && markers.length > 0
                ? markers.map((marker, i) => (
                        <MapView.Marker
                            coordinate={{
                                longitude: marker.loc.coordinates[0],
                                latitude: marker.loc.coordinates[1],
                            }}
                            key={`marker-${i}`}
                            style={{height: 20, width: 20}}
                            onPress={e => markerClick(e, marker)}
                            image={
                                this.props.selectedMarker === marker._id
                                    ? selectedMarkerImage
                                    : normalMarkerImage
                            }
                        />
                  ))
                : null}
        </MapView>
    ) : null;
  }
}

component Function

markerClick = async (event, data) => {
    this.props.dispatch(
        setMarkerIconInRedux(this.state.popover.currentData._id)
    );
};

操作

export const setMarkerIconInRedux = where => {
    return {
        type: 'SET_MARKER_ICON',
        _id: where,
    };
};

Redux
export const currentSelectedMarker = (state = {selectedMarker: ''}, action) => 
{
    if (action.type === 'SET_MARKER_ICON') {
        return {selectedMarker: action._id};
    } else if (action.type === 'REMOVE_MARKER_ICON') {
        return {selectedMarker: ''};
    } else {
        return state;
    }
};

1

我通过将16位伽马整数图像替换为8位伽马整数图像来解决了这个问题。可以在Gimp中完成,导出图像时选择8bpc RGBA。


请问您能否添加一个示例呢? - Abdu4
1
这不是关于编码,而是关于替换图像。您的图像应该是8位伽马整数格式。 - Vladimír

0

<View>中添加您的自定义标记组件,例如:<View> 您的标记自定义视图 </View>。这样或许可以解决您的问题。


0

对于我的情况,问题仅出现在远程图像上,因此我通过一种hack方法解决了它。

我只是在Text组件内部放置了一个零宽度的图像版本,并在Text组件外部放置了另一个版本。突然间,所有问题都得到了解决。

    <Image
     source={{ uri: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" }}
     style={styles.companyLogoMarker}
     resizeMode="cover"
     />
     <Text style={styles.markerText}>
        {names?.[0]?.value}
       <Image
           source={{ uri: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" }}
           style={{width: 0, height: 0}}
           resizeMode="cover"
        />
     </Text>

截至撰写本答案时,[react native maps][1]存在一个错误,自2017年以来尚未解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接