最近我一直在困扰这个问题,希望根据地图标记是否被选中/激活来动态更新地图标记图像(每个MapMarker都有一个类别,引用两个图像集interestIcons和interestIconsSelected中的活动图像或默认图像。基本上,我有一组MapMarkers,通过映射渲染出来,每个MapMarker是MapView.Marker的子组件。
我想在默认未选择/非激活状态下呈现所有MapMarkers,使用interestIcons中的默认图像,当选择时,该MapMarker图像应更改为从interestIconsSelected中选择的活动图像,当选择另一个MapMarker时,先前选择的应恢复为默认图像,新的应更改为所选图像。
目前,我可以使用默认图像呈现地图标记,但当选择地图标记时,图像似乎不会立即更改,除非您再次缩放/缩小以引起某种重新渲染,我希望单击MapMarker会立即导致图像更新。
MapScreen.js: 通过map渲染出所有MapView.Marker MapMarkers的MapView。
<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}
/>
)
}
}
componentWillReceiveProps(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下定义Image组件,但这并不起作用。
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下直接使用Image组件,都不如使用MapMarker子组件好。
this.props.selected.id === this.props.event.id ? interestIconsSelected[this.props.event.interest[0]] : interestIcons[this.props.event.interest[0]];
- Michael