-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Images inside Marker views are not always rendered on Android #100
Comments
@priithaamer What version of android are you running? |
I've seen it with devices running Android 5.1. Had no chance to check with other versions yet. |
I'm also facing this issue. If I set image source attribute
Shows |
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. |
I've also experienced this. It usually seems to happen on the first marker being placed. |
Also having this issue. It generally occurs when I first use an icon. Even if a marker renders correctly the first time, if I switch the marker state such that a different icon is used, the new icon will not be rendered. If I switch it back to the original, and then again back to the second icon, the second icon renders correctly. It might be related to whether the image has fully loaded by the time the marker is processed. My marker definition is as follows:
Versions:
|
I have similar issue. |
Did anyone find a workaround for this issue?? |
I still was not able to resolve the problem. Very frustrating(.. |
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> |
@lellex I tried your solution but didn't work for me :( |
@lellex I also used this approach to make workaround, and I thought it solved the problem. But after some testing I found cases when even this hack will not help. Believe me, it will not work in 100%. |
I had the same issue. |
+1 |
+1 |
1 similar comment
+1 |
+1 A workaround is to initially render an invisible Image and then render the MapView after the image icon has loaded:
Alternatively update the marker after the image loads:
Downside of this is that the user sees the icon 'pop' into the empty marker. |
+1 |
Same problem here, and its on the ios simulator as well as android. |
+1, Same with android 6.0 emulator |
@jonesdar Thank you for that fix!! It's been incredibly helpful. |
@jonesdar thanks mate, worked for me as well! |
I solved this problem for now by declaring an |
How is that you did that? |
@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. |
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. |
Sorry I can't help now, that workaround was enough at the time for me. Hope this gets fixed 😃 |
@betiol That is not a replacement solution because
|
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. |
@hiddentao does your workaround works with remote images { uri: 'http://someresource...' } ? |
The problem with @hiddentao solution is that you can not set a Also, workarounds about loading |
This is for callouts, but I believe the problem is the same thing. If I click Marker A, nothing will show but an empty white box. Then I'll click Marker B and it won't load either. Then I'll click Marker A again and it still won't load anything. I'll click Marker B, still nothing. My next click on Marker A will show the image. My next back to Marker B will also show the image. Try it. It works every time. A, B, A, B, A (works), B (works). 5th and 6th clicks. So a marker needs to be tapped 3 times. You can replicate this by just tapping a marker 3 times.
|
yet another workaround in case you're rendering a dynamic list of markers (which in my case are region based, so everytime the user changes the region I make a request and rerender new markers). <Marker /> component const Marker = ({
coordinate,
following,
image,
loaded,
onLoad,
onPress,
}) => (
<MapView.Marker
style={styles.marker}
coordinate={coordinate}
onPress={onPress}
>
<View>
{(image && !loaded) &&
<Image
source={image}
style={styles.invisible}
onLoad={onLoad}
/>
}
{(!image || !loaded) &&
<View style={styles.container}>
<Icon name="logo" size={35} color="#432A5F" />
</View>
}
{(image && loaded) &&
<Image
source={image}
style={styles.image}
/>
}
</View>
</MapView.Marker>
); <Markers /> component const Markers = ({
markers,
onMarkerPress,
onMarkerLoad,
}) => (
<View>
{markers.map(m =>
<Marker
{...m}
key={m.id}
onPress={() => onMarkerPress(m.id)}
onLoad={() => onMarkerLoad(m.id)}
/>,
)}
</View>
); So you have to include a flag "loaded" for every marker in order to know which ones were loaded. I Hope you find this helpful :) |
@tugorez I haven't tried it with remote images, sorry. For Android it probably won't work since the documentation states that the image must be local. @MathieuMailhos You're right, the Android image can't be styled. Then again, I only needed to control the size of the marker, nothing else. |
A project that I'm working on also ran into this bug Like others said, a work around can be done through
Here is what I know
What I have not tried
I saw else where |
Im sorry not to being enough prepared (I'm not an Android nor IOS developer) to fix this bug :/ . import React, { Component, PropTypes } from 'react';
import { Image, View } from 'react-native';
import MapView from 'react-native-maps';
import Icon from 'components/Icon';
import styles from './styles';
class Marker extends Component {
constructor(props) {
super(props);
this.state = { loaded: false };
}
onLoad() {
this.setState({ loaded: true });
}
render() {
const { image, latitude, longitude, onPress } = this.props;
const loaded = image && this.state.loaded;
const onLoad = this.onLoad.bind(this);
return (
<MapView.Marker coordinate={{ latitude, longitude }} onPress={onPress}>
<View style={styles.container}>
{ loaded &&
<Image source={{ uri: image }} style={styles.image} />
}
{ !loaded &&
<View style={styles.logo}>
<Icon name="logo" color="#4A0063" size={35} />
<Image source={{ uri: image }} onLoad={onLoad} />
</View>
}
</MapView.Marker>
);
}
}
Marker.propTypes = {
image: PropTypes.string,
latitude: PropTypes.number,
longitude: PropTypes.number,
onPress: PropTypes.func,
};
export default Marker; The <Icon /> component will put a "default" image as an icon while the "real" image is loaded. |
just a heads up, i solved my problem by removing |
I solved this issue by using the same image again outside the mapViw. but with 0 width and 0 height.
So that Constants.Images.MarkerImage will load before mapView loads markers. |
Hey guys, I've been having issues with this and nothing was working. I am displaying an image with some text over the top of it and I would only ever see the text. It works now though by using both <Marker source... AND my custom view. eg. <MapView.Marker
As you can see, there's a little bit of faff with aligning text image and this may be a pixel or two out on some devices but so far its the best I've come up with and seems to work on every device/OS I've tested so far. Hope it helps someone. Martin |
I can confirm this bug still happens. I use my custom view as a marker:
|
@yonahforst thank you, it works for me. |
@yaronlevi I have the same issue. RN: 0.41 |
I had the same issue with: I seem to have solved it by using a module for all my assets and having a HOC preload them before displaying any other part of the app. assets.ts export const images = {
myCoolIcon: require('../../assets/images/my-cool-icon.png')
} AssetPreloader.tsx import * as Assets from '../assets'
import * as React from 'react'
import { Image, View } from 'react-native'
export class AssetPreloader extends React.Component<any, any> {
constructor(props: any) {
super(props)
const images = Object.values(Assets.images)
this.incLoadCount = this.incLoadCount.bind(this)
this.state = { preloaded: 0, total: images.length, images: Assets.images }
}
render() {
return (
<View style={ { opacity: 0, position: 'absolute' } }>
{ Object.entries(this.state.images).map(([ key, src ]: any) => <Image key={ key } source={ src } onLoad={ this.incLoadCount } />) }
</View>
)
}
private incLoadCount() {
this.setState({ preloaded: this.state.preloaded + 1 }, () => {
if (this.state.preloaded >= this.state.total) this.props.onComplete()
})
}
} App.tsx import * as React from 'react'
import { AssetPreloader } from './components/AssetPreloader'
export class App extends React.Component<any, any> {
constructor(props: {}) {
super(props)
this.donePreloadingAssets = this.donePreloadingAssets.bind(this)
this.state = { loading: true }
}
render() {
return (
this.state.loading ?
<Preloader onComplete={ this.donePreloadingAssets } />
:
<MainContent />
)
}
private donePreloadingAssets() {
this.setState({ loading: false })
}
} |
Merging to #1870 |
+1 |
I have found a workaround of this problem. first you set the coordinate into an animated region.
and then you update the marker with new coordinates, in the following way. Note: placing marker Image component before Mapview will also solve the issue. However, when you drag/pan the map it will not move the marker around, the marker will stay in the same place. |
Working solution: #2734 (comment) |
When using images within custom views on Markers like this, they are not always rendered on Android (sometimes they appear though):
With
adb logcat
i always see this error when image is not rendered:Images on markers only appear correctly on Android, when using
<Marker image="..." />
I'm using React Native 0.20
The text was updated successfully, but these errors were encountered: