React Native Maps: Markers image doesn't show using Custom Marker in react-native-maps

百般思念 提交于 2019-12-20 12:20:16

问题


I'm using react-native-maps but I faced a problem that after a lot of googling without answer makes me ask it here. I'm trying to use Custom Marker for the marker in the map as the following picture

  • as I searched I found out that needed to use Custom Marker to accomplish the maker's design, then I created a Custom Marker component

    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;
    

when I use CustomMarker.js class solely it works fine and it shows the image but when I use it as the marker custom view it doesn't show the image

I don't know why it can't render the image with Custom Marker in android. and here is my code where I'm using map, markers and custom marker class

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>

any kind of help would be appreciated.


回答1:


Use SVG for this 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>



回答2:


My problem was solved right now.

I hope your problem will be solved.

This is my clean code:

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>
        );
    }
}



回答3:


I had the same problem.

When you first load an application, the image does not show, but for later loading, this problem is resolved and show image.

Just enough after the image is loaded call this.forceUpdate()

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

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

You can track this:

https://github.com/react-community/react-native-maps/issues/924




回答4:


@Mahdi Bashirpour solution works for me. just upgrading above answer.

Other Images stop working if we import 'Image' from 'react-native-svg'

My solution is below.

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>

Use 'Imagesvg' for marker image. It's working for me on android 7 and 8. React native version '0.55.3'




回答5:


This is another example

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>
    )
  }
}



回答6:


I Had same problem , from github post

using below(MapView , Image) pattern first load problem will still occour

<MapView.Marker>
    <Image source={img_marker} />
</MapView.Marker>

so adopted below solution : trick is to save current selected marker id in 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)
    );
};

Action

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;
    }
};



回答7:


I solved this issue by replacing 16-bit gamma integer Image with 8-bit gamma integer Image. It can be done in Gimp, once exporting Image select 8bpc RGBA.




回答8:


as of Oct 2019, the image can be displayed in the marker as along as the tracksViewChanges is set to true. I use FastImage but the general idea is to set tracksViewChanges to true and then to false as soon as the image is loaded so that there won't be any performance issue.

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>
  );
};


来源:https://stackoverflow.com/questions/51915353/react-native-maps-markers-image-doesnt-show-using-custom-marker-in-react-nativ

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!