Images inside Marker views are not always rendered on Android

When using images within custom views on Markers like this, they are not always rendered on Android (sometimes they appear though):

<MapView.Marker coordinate={...}>
  <View>
    <Image source={require('./image.png')} />
  </View>
</MapView.Marker>

With adb logcat i always see this error when image is not rendered:

E/unknown:DraweeEventTracker(19143): 1b82b058: Draw requested for a non-attached controller e80013b. DraweeHolder{controllerAttached=false, holderAttached=false, drawableVisible=true, activityStarted=true, events=[ON_SET_HIERARCHY, ON_SET_CONTROLLER]}

Images on markers only appear correctly on Android, when using <Marker image="..." />

I’m using React Native 0.20

15 thoughts on “Images inside Marker views are not always rendered on Android

  1. I’m facing the same issue, android 6.0 with RN version 0.20.

        <MapView.Marker
          key={car.key}
          coordinate={car.coordinates}
        >
          <Image source={pin} style={styles.pin} />
        </MapView.Marker>

    Sometimes some markers are rendered without the image.

  2. I had the same issue. The only way I found is to declare marker’s images before MapView.

     <View style={styles.map}>
         {this.state.markers.map(marker => (
             <Image source={{uri: marker.image}} />
         ))}
         <MapView>
             {this.state.markers.map(marker => (
                 <MapView.Marker
                     key={marker.id}
                     coordinate={marker.latlng}>
                     <Image source={{uri: marker.image}} style={{width: 42, height: 42}} />
                 </MapView.Marker>
             ))}
         </MapView>
     </View>
  3. +1

    A workaround is to initially render an invisible Image and then render the MapView after the image icon has loaded:

    render() {
      let renderContent = null;
      if (!this.state.iconLoaded) {
        renderContent = <Image style={{opacity: 0}} source={MY_ICON} onLoadEnd={() => {this.setState({iconLoaded: true});}}/>
      } else {
        renderContent = <MapView> etc.
      }
      return renderContent;
    }
    

    Alternatively update the marker after the image loads:

    <MapView.Marker
      key={this.state.iconLoaded ? 'markerLoaded' : 'marker'}>
      <Image source={MY_ICON} onLoadEnd={() => {if (!this.state.iconLoaded) this.setState({iconLoaded: true});}}/>
    </MapView.Marker>
    

    Downside of this is that the user sees the icon ‘pop’ into the empty marker.

  4. Has someone a clue why this is happening? And a solution without workarounds? For me it happens when i try to load more pins some of the images are then removed. The pins themself are still existing.

  5. To get things working nicely on both Android and iOS (RN 0.40, Maps 0.13) I do:

    const isAndroid = (Platform.OS === 'android')
    const key = 'uniqueMarkerKey'
    const markerImage = require('../images/marker.png') /* 480x480px */
    
    return(
          <MapView.Marker
            key={key}
            anchor={{x: 0.5, y: 0.5}}
            flat={true}
            image={isAndroid ? markerImage : null}
            identifier={key}
            coordinate={{ latitude: .., longitude: }}
          >
            {isAndroid ? null : <Image source={markerImage} style={{ width: 480, height: 480 }} />}
          </MapView.Marker>
    )

    The limitation here is that the marker image needs to already be sized correctly for Android – but for iOS you can then use the style attribute to correct the width/height for display.

  6. I solved this issue by using the same image again outside the mapViw. but with 0 width and 0 height.

    <Image style={{width:0,height:0}} source={ Constants.Images.MarkerImage } />

    So that Constants.Images.MarkerImage will load before mapView loads markers.

Comments are closed.

Images inside Marker views are not always rendered on Android

When using images within custom views on Markers like this, they are not always rendered on Android (sometimes they appear though):

<MapView.Marker coordinate={...}>
  <View>
    <Image source={require('./image.png')} />
  </View>
</MapView.Marker>

With adb logcat i always see this error when image is not rendered:

E/unknown:DraweeEventTracker(19143): 1b82b058: Draw requested for a non-attached controller e80013b. DraweeHolder{controllerAttached=false, holderAttached=false, drawableVisible=true, activityStarted=true, events=[ON_SET_HIERARCHY, ON_SET_CONTROLLER]}

Images on markers only appear correctly on Android, when using <Marker image="..." />

I’m using React Native 0.20

12 thoughts on “Images inside Marker views are not always rendered on Android

  1. I’m facing the same issue, android 6.0 with RN version 0.20.

        <MapView.Marker
          key={car.key}
          coordinate={car.coordinates}
        >
          <Image source={pin} style={styles.pin} />
        </MapView.Marker>

    Sometimes some markers are rendered without the image.

  2. I had the same issue. The only way I found is to declare marker’s images before MapView.

     <View style={styles.map}>
         {this.state.markers.map(marker => (
             <Image source={{uri: marker.image}} />
         ))}
         <MapView>
             {this.state.markers.map(marker => (
                 <MapView.Marker
                     key={marker.id}
                     coordinate={marker.latlng}>
                     <Image source={{uri: marker.image}} style={{width: 42, height: 42}} />
                 </MapView.Marker>
             ))}
         </MapView>
     </View>
  3. +1

    A workaround is to initially render an invisible Image and then render the MapView after the image icon has loaded:

    render() {
      let renderContent = null;
      if (!this.state.iconLoaded) {
        renderContent = <Image style={{opacity: 0}} source={MY_ICON} onLoadEnd={() => {this.setState({iconLoaded: true});}}/>
      } else {
        renderContent = <MapView> etc.
      }
      return renderContent;
    }
    

    Alternatively update the marker after the image loads:

    <MapView.Marker
      key={this.state.iconLoaded ? 'markerLoaded' : 'marker'}>
      <Image source={MY_ICON} onLoadEnd={() => {if (!this.state.iconLoaded) this.setState({iconLoaded: true});}}/>
    </MapView.Marker>
    

    Downside of this is that the user sees the icon ‘pop’ into the empty marker.

  4. I solved this problem for now by declaring an <Image> before <MapView>. Using React Native 0.29.2.

  5. @felipegarcia92, and for future reference:

    By adding an image element before the mapview in the render function. I’ve verified this myself, eg:

    <Image
    style={{opacity: 0}}
    source={require('SRC_OF_IMAGE')}
    />
    <MapView />

    This ensures that the image resource for the marker is loaded before the mapview tries to render it, I guess.

  6. Has someone a clue why this is happening? And a solution without workarounds? For me it happens when i try to load more pins some of the images are then removed. The pins themself are still existing.

  7. To get things working nicely on both Android and iOS (RN 0.40, Maps 0.13) I do:

    const isAndroid = (Platform.OS === 'android')
    const key = 'uniqueMarkerKey'
    const markerImage = require('../images/marker.png') /* 480x480px */
    
    return(
          <MapView.Marker
            key={key}
            anchor={{x: 0.5, y: 0.5}}
            flat={true}
            image={isAndroid ? markerImage : null}
            identifier={key}
            coordinate={{ latitude: .., longitude: }}
          >
            {isAndroid ? null : <Image source={markerImage} style={{ width: 480, height: 480 }} />}
          </MapView.Marker>
    )

    The limitation here is that the marker image needs to already be sized correctly for Android – but for iOS you can then use the style attribute to correct the width/height for display.

Comments are closed.