I was recently puzzled by this, and I want to dynamically update map marker images based on whether the map marker is selected / active or not (each MapMarker has a category that refers to either the active image or the default image from two image collections: interest and IconsSelected interest.In essence, I have a collection of MapMarkers that are displayed with display through a collection of map markers.Each MapMarker is a child component of MapView.Marker.
I would like to display all MapMarkers in the unselected / inactive default state, having a default image from objects of interest, when it is selected that the MapMarker image should be changed to the active image from the list of interestsIconsSelected, when another MapMarker selected the previous one should return to the default image , and the new one should change to the selected image.
Currently, I can display map markers with a default image, but when choosing mapmarker the image does not seem to change immediately if you do not want to zoom in / out again, i.e. -render, I would like so that clicking on MapMarker immediately caused the image to refresh.
MapScreen.js: Displays MapView for all MapView.Marker MapMarkers through the map.
<MapView ref={map => { this._map = map }} style={Styles.Map.map} initialRegion={this.props.region} onRegionChange={this.handleRegionChange} > { this.props.events .filter(this.eventFilterTimeNearFuture) .filter(this.eventFilterTimeNotPast) .filter(this.eventFilterDistance) .filter(this.eventFilterInterest) .map(e => <MapView.Marker key={e.id} onPress={() => this.handleLocationPush(e)} // Set selected event state coordinate={e.location} > <MapMarker event={e} size={this.state.markerSize} selected={this.state.selectedEvent} // The selected event set by state call. /> </MapView.Marker> ) } { !this.props.regionMock && <MapView.Marker key={'userLocation'} coordinate={this.props.region} > <MapMarker size={'user'} /> </MapView.Marker> } </MapView>
MapMarker.js
import {interestIcons, interestColors, interestIconsSelected} from "../../utils/Icons"; import {Styles} from '../../StyleProvider'; class MapMarker extends React.Component { constructor() { super(); this.state = { initialized: false, active: false, }; }; componentWillReceiveProps(nextProps) { if (!this.state.initialized) { console.log('initialization'); this.setState({initialized: true}); } else {
The WillReceiveProps (nextProps) component still works, and this points to the "fairly good" current selected event and all unselected events.
I tried to set the image source using say this.state.image and then setting the state of the image in the this.state.image component accordingly, i.e.
if (nextProps.selected) { // If the nextProps.selected props id equals the this event id then selected else non-selected. if (nextProps.selected.id === nextProps.event.id) { console.log('SELECTED: ' + JSON.stringify(nextProps.selected)); // set staae to active this.setState({ active: true, image: this.markerIcon(nextProps.event.interest[0], true) }); console.log(interestIconsSelected[nextProps.event.interest[0]]); } else { // set state to not active console.log('NON-SELECTED: ' + JSON.stringify(nextProps.event)); this.setState({ active: false, image: this.markerIcon(nextProps.event.interest[0], false) }); } } renderIcon() { if (this.props.event.type === 'Event') { return ( <Image source={this.state.image} style={Styles.MapMarker.eventImage} /> ) } }
Changing the state of the image seems to work more efficiently, as the image will immediately change, but then it seems that the image on the original render will not be set at all, so it will be a blank icon until it is selected.
Thanks a lot, appreciate any help.
Update: Trying to define an image component in MapView.Marker and this will not work.
this.state.markers .map(e => <MapView.Marker key={e.id} onPress={() => this.handleLocationPush(e)} coordinate={e.location} > {/* <MapMarker event={e} size={this.state.markerSize} /> */} <Image source={this.state.selectedEvent === e ? interestIconsSelected[e.interest[0]] : interestIcons[e.interest[0]]} style={Styles.MapMarker.eventImage} /> </MapView.Marker> )
BUT this works, although you seem to be unable to apply style to MapView.Marker, but this is not an implementation, I would like for me to save the custom MapMarker component
this.state.markers .map(e => <MapView.Marker key={e.id} onPress={() => this.handleLocationPush(e)} coordinate={e.location} image={this.state.selectedEvent === e ? interestIconsSelected[e.interest[0]] : interestIcons[e.interest[0]]} /> )
The above two snipers of the code, either using the image, refer directly to MapView.Marker, or have the image component directly in MapView.Marker are not suitable, as using the child component MapMaper.