Недавно я был озадачен этим, и я хочу динамически обновлять изображения маркеров карты в зависимости от того, выбран ли маркер карты / активен или нет (каждый MapMarker имеет категорию, которая ссылается либо на активное изображение, либо на изображение по умолчанию из две коллекции изображений: InterestIcons и InterestIconsSelected. По сути, у меня есть коллекция MapMarkers, которые отображаются с отображением через коллекцию маркеров карты. Каждый MapMarker является дочерним компонентом MapView.Marker.
Я хотел бы отобразить все MapMarker в невыбранном / неактивном состоянии по умолчанию с изображением по умолчанию из InterestIcons, когда он выбран, это изображение MapMarker должно измениться на активное изображение из InterestIconsSelected, когда выбран другой MapMarker, предыдущий выбранный должен вернуться к изображению по умолчанию, а новое должно измениться на выбранное изображение.
В настоящее время я могу визуализировать маркеры карты с изображением по умолчанию, но при выборе маркера карты изображение, похоже, не меняется сразу, если только вы не уменьшили / не увеличили масштаб снова, то есть вызвать какой-то повторный рендеринг, Я бы хотел, чтобы при нажатии на MapMarker изображение сразу обновлялось.
MapScreen.js: отображает MapView для всех MapView.Marker MapMarkers через карту.
<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 {
// If the nextProps.selected prop exists which it will
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
});
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
});
}
this.forceUpdate();
}
}
}
markerIcon(interest) {
return this.state.active ? interestIconsSelected[interest] : interestIcons[interest];
}
renderIcon() {
if (this.props.event.type === 'Event') {
return (
<Image
source={this.markerIcon(this.props.event.interest[0])}
style={Styles.MapMarker.eventImage}
/>
)
}
}
КомпонентWillReceiveProps (nextProps) все еще находится в стадии разработки, и это указывает «достаточно хорошо» на текущее выбранное событие и все невыбранные события.
Я попытался установить источник изображения для использования, скажем, this.state.image
, а затем установить состояние изображения в componentWillReceiveProps соответственно, т.е.
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}
/>
)
}
}
Изменение состояния изображения, похоже, работает более эффективно, поскольку изображение изменится немедленно, но тогда кажется, что изображение при первоначальном рендеринге вообще не будет установлено, поэтому это будет просто пустой значок, пока он не будет выбран.
Большое спасибо, ценю любую помощь.
Обновление: Попытка определить компонент изображения в MapView.Marker, и это не работает.
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>
)
НО это работает, хотя вы, похоже, не можете применить стиль к MapView.Marker, но это не та реализация, которую я хотел бы, поскольку я хотел бы сохранить настраиваемый компонент MapMarker
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]]}
/>
)
Вышеупомянутые два фрагмента кода с использованием свойства изображения непосредственно в MapView.Marker или с компонентом изображения непосредственно в MapView.Marker не подходят для использования дочернего компонента MapMaper.