React Native Maps:在 react-native-maps 中使用自定义标记不显示标记图像
React Native Maps: Markers image doesn't show using Custom Marker in react-native-maps
我正在使用 react-native-maps
,但我遇到了一个问题,在谷歌搜索了很多都没有答案之后,我不得不在这里提问。
我正在尝试使用 Custom Marker 作为地图中的标记,如下图
在搜索中发现需要使用Custom Marker来完成maker的设计,于是我创建了一个Custom Marker组件
import React, { Component } from "react";
import { View } from "react-native";
import {
Text,
Left,
Right,
Thumbnail,
} from "native-base";
const defaultEmployeeLogo = require("../../../assets/defualtEmployee.png");
class CustomMarker extends Component {
render() {
return (
<View style={{ flexDirection: 'row', width: 140, height: 60,
borderRadius: 70, backgroundColor: 'orange' }}>
<Left>
<Thumbnail source={defaultEmployeeLogo} />
</Left>
<Right>
<Text style={{
color: '#fef',
fontSize: 13,
paddingBottom: 2,
fontFamily: 'Roboto',
alignItems: 'center',
paddingRight: 10
}}>Mohammad</Text>
</Right></View >);
}
}
export default CustomMarker;
当我单独使用 CustomMarker.js class 时它工作正常并且显示图像但是当我将它用作标记自定义视图时它不显示图像
我不知道为什么它不能在android中渲染带有自定义标记的图像。
这是我使用地图、标记和自定义标记的代码 class
return (
<View style={styles.map_container}>
<MapView
style={styles.map}
customMapStyle={customrMapStyle}
region={{
latitude: this.state.region.latitude,
longitude: this.state.region.longitude,
latitudeDelta: 0.4,
longitudeDelta: 0.41,
}} >
{
coordinationData.map(function (marker, i) {
let lat = marker.latLang.latitude;
let lang = marker.latLang.longitude;
<MapView.Marker
key={i}
coordinate={
{
latitude: lat,
longitude: lang,
latitudeDelta: 0.4,
longitudeDelta: 0.41
}
}
title={marker.title}
description={marker.description}
>
<CustomMarker />
</MapView.Marker>
})}
</MapView>
</View>
如有任何帮助,我们将不胜感激。
我遇到了同样的问题。
当您第一次加载应用程序时,图像不显示,但在稍后加载时,此问题已解决并显示图像。
图片加载完成后调用this.forceUpdate()
const defaultEmployeeLogo = require("../../../assets/defualtEmployee.png");
<Image source={defaultEmployeeLogo} onLoad={() => this.forceUpdate()}>
<Text style={{width:0, height:0}}>{Math.random()}</Text>
</Image>
你可以追踪这个:
https://github.com/react-community/react-native-maps/issues/924
这是另一个例子
class PinMarker extends Component {
state = {
initialRender: true
}
render() {
return (
<MapView.Marker coordinate={coordinate}>
<Image
source={...}
onLayout={() => this.setState({ initialRender: false })}
key={`${this.state.initialRender}`}
/>
</MapView.Marker>
)
}
}
我的问题现在已经解决了。
希望你的问题得到解决
这是我的干净代码:
import React, {Component} from 'react';
import {ImageBackground, Text} from 'react-native';
import {Marker} from 'react-native-maps';
export default class CustomMarker extends Component {
state = {
initialRender: true
}
render() {
return (
<Marker
//...
>
<ImageBackground
source={require('../assets/cluster3_mobile.png')}>
// *** These lines are very important ***
onLoad={() => this.forceUpdate()}
onLayout={() => this.setState({initialRender: false})}
key={`${this.state.initialRender}`}
>
// **** This line is very very important ****
<Text style={{width: 0, height: 0}}>{Math.random()}</Text>
</ImageBackground>
</Marker>
);
}
}
我有同样的问题,from github post
使用 below(MapView , Image) pattern first load 问题仍然会发生
<MapView.Marker>
<Image source={img_marker} />
</MapView.Marker>
所以采用了以下解决方案:技巧是在 redux 中保存当前选择的标记 id
class Map extends React.Component {
render() {
let {region, markers , markerClick} = this.props;
const normalMarkerImage = require('../../images/normal_marker.png');
const selectedMarkerImage = require('../../images/selected_marker.png');
return !isObjectEmpty(region) && !isObjectEmpty(markers) ? (
<MapView
style={styles.map}
showsUserLocation={true}
followUserLocation={true}
zoomEnabled={true}
region={region}
paddingAdjustmentBehavior={'automatic'}
showsIndoors={true}
showsIndoorLevelPicker={false}
showsTraffic={false}
toolbarEnabled={false}
loadingEnabled={true}
showsMyLocationButton={true}>
{markers && markers.length > 0
? markers.map((marker, i) => (
<MapView.Marker
coordinate={{
longitude: marker.loc.coordinates[0],
latitude: marker.loc.coordinates[1],
}}
key={`marker-${i}`}
style={{height: 20, width: 20}}
onPress={e => markerClick(e, marker)}
image={
this.props.selectedMarker === marker._id
? selectedMarkerImage
: normalMarkerImage
}
/>
))
: null}
</MapView>
) : null;
}
}
组件函数
markerClick = async (event, data) => {
this.props.dispatch(
setMarkerIconInRedux(this.state.popover.currentData._id)
);
};
动作
export const setMarkerIconInRedux = where => {
return {
type: 'SET_MARKER_ICON',
_id: where,
};
};
Redux
export const currentSelectedMarker = (state = {selectedMarker: ''}, action) =>
{
if (action.type === 'SET_MARKER_ICON') {
return {selectedMarker: action._id};
} else if (action.type === 'REMOVE_MARKER_ICON') {
return {selectedMarker: ''};
} else {
return state;
}
};
为此https://github.com/react-native-community/react-native-svg
使用SVG
<Marker
coordinate={{
longitude: lang,
latitude: lat,
}}
>
<View style={{
flexDirection: 'row', width: 100, height: 30,
backgroundColor: 'orange'
}}>
<Svg
width={40} height={30}>
<Image
href={url}
width={40}
height={30}
/>
</Svg>
<View
style={{
flexDirection: 'column'
}}
>
<Text
style={{
marginLeft: 2,
fontSize: 9,
color: '#ffffff',
fontWeight: 'bold',
textDecorationLine: 'underline'
}}
>{marker.title}</Text>
<Text
style={{
marginLeft: 2,
fontSize: 9,
color: '#ffffff',
fontWeight: 'bold',
textDecorationLine: 'underline'
}}
>{marker.description}</Text>
</View>
</View>
</Marker>
@Mahdi Bashirpour 解决方案对我有用。只是升级上面的答案。
如果我们从 'react-native-svg'
导入 'Image',其他图像将停止工作
我的解决方案如下。
import {Image} from 'react-native'; // for other images in our render method.
import { Image as Imagesvg } from 'react-native-svg';
<Marker
coordinate={marker.latlng}
title={marker.title}
>
<View style={{ height: 90, width: 90, backgroundColor: 'orange' }}>
<Svg width={90} height={90}}>
<Imagesvg href={marker_g} width={90} height={90} /> // Local Images
<Imagesvg href={{uri:url}} width={90} height={90} /> //Server images
</Svg>
</View>
</Marker>
对标记图像使用'Imagesvg'。
它在 android 7 和 8 上为我工作。React 本机版本 '0.55.3'
我通过用 8 位伽玛整数图像替换 16 位伽玛整数图像解决了这个问题。可以在 Gimp 中完成,一旦导出图像 select 8bpc RGBA。
自 2019 年 10 月起,只要将 tracksViewChanges 设置为 true,图像就可以显示在标记中。我使用 FastImage,但一般的想法是将 tracksViewChanges 设置为 true,然后在图像加载后立即设置为 false,这样就不会有任何性能问题。
export const UserMapPin = props => {
const [trackView, setTrackView] = useState(true);
function changeTrackView() {
setTrackView(false);
}
return (
<Marker
tracksViewChanges={trackView}
coordinate={props.coordinates}>
<View style={styles.imageIconContainer}>
<FastImage
onLoadEnd={changeTrackView}
style={styles.someImageStyle}
source={{
uri: props.imageURI,
}}
resizeMode={FastImage.resizeMode.cover}
/>
</View>
</Marker>
);
};
就我而言,问题仅出在远程图像上,因此我通过 hack 解决了它。
我只是在文本组件中放置了一个零宽度的图像版本,在文本组件外部放置了一个版本。突然一切都解决了。
<Image
source={{ uri: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" }}
style={styles.companyLogoMarker}
resizeMode="cover"
/>
<Text style={styles.markerText}>
{names?.[0]?.value}
<Image
source={{ uri: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" }}
style={{width: 0, height: 0}}
resizeMode="cover"
/>
</Text>
在撰写此答案时,这是 [react native maps][1]
中的错误,自 2017 年以来未解决
在 <View>
中添加自定义标记组件
例如<View> your marker custom view </View>
。也许它会解决您的问题。
我正在使用 react-native-maps
,但我遇到了一个问题,在谷歌搜索了很多都没有答案之后,我不得不在这里提问。
我正在尝试使用 Custom Marker 作为地图中的标记,如下图
在搜索中发现需要使用Custom Marker来完成maker的设计,于是我创建了一个Custom Marker组件
import React, { Component } from "react"; import { View } from "react-native"; import { Text, Left, Right, Thumbnail, } from "native-base"; const defaultEmployeeLogo = require("../../../assets/defualtEmployee.png"); class CustomMarker extends Component { render() { return ( <View style={{ flexDirection: 'row', width: 140, height: 60, borderRadius: 70, backgroundColor: 'orange' }}> <Left> <Thumbnail source={defaultEmployeeLogo} /> </Left> <Right> <Text style={{ color: '#fef', fontSize: 13, paddingBottom: 2, fontFamily: 'Roboto', alignItems: 'center', paddingRight: 10 }}>Mohammad</Text> </Right></View >); } } export default CustomMarker;
当我单独使用 CustomMarker.js class 时它工作正常并且显示图像但是当我将它用作标记自定义视图时它不显示图像
我不知道为什么它不能在android中渲染带有自定义标记的图像。 这是我使用地图、标记和自定义标记的代码 class
return (
<View style={styles.map_container}>
<MapView
style={styles.map}
customMapStyle={customrMapStyle}
region={{
latitude: this.state.region.latitude,
longitude: this.state.region.longitude,
latitudeDelta: 0.4,
longitudeDelta: 0.41,
}} >
{
coordinationData.map(function (marker, i) {
let lat = marker.latLang.latitude;
let lang = marker.latLang.longitude;
<MapView.Marker
key={i}
coordinate={
{
latitude: lat,
longitude: lang,
latitudeDelta: 0.4,
longitudeDelta: 0.41
}
}
title={marker.title}
description={marker.description}
>
<CustomMarker />
</MapView.Marker>
})}
</MapView>
</View>
如有任何帮助,我们将不胜感激。
我遇到了同样的问题。
当您第一次加载应用程序时,图像不显示,但在稍后加载时,此问题已解决并显示图像。
图片加载完成后调用this.forceUpdate()
const defaultEmployeeLogo = require("../../../assets/defualtEmployee.png");
<Image source={defaultEmployeeLogo} onLoad={() => this.forceUpdate()}>
<Text style={{width:0, height:0}}>{Math.random()}</Text>
</Image>
你可以追踪这个:
https://github.com/react-community/react-native-maps/issues/924
这是另一个例子
class PinMarker extends Component {
state = {
initialRender: true
}
render() {
return (
<MapView.Marker coordinate={coordinate}>
<Image
source={...}
onLayout={() => this.setState({ initialRender: false })}
key={`${this.state.initialRender}`}
/>
</MapView.Marker>
)
}
}
我的问题现在已经解决了。
希望你的问题得到解决
这是我的干净代码:
import React, {Component} from 'react';
import {ImageBackground, Text} from 'react-native';
import {Marker} from 'react-native-maps';
export default class CustomMarker extends Component {
state = {
initialRender: true
}
render() {
return (
<Marker
//...
>
<ImageBackground
source={require('../assets/cluster3_mobile.png')}>
// *** These lines are very important ***
onLoad={() => this.forceUpdate()}
onLayout={() => this.setState({initialRender: false})}
key={`${this.state.initialRender}`}
>
// **** This line is very very important ****
<Text style={{width: 0, height: 0}}>{Math.random()}</Text>
</ImageBackground>
</Marker>
);
}
}
我有同样的问题,from github post
使用 below(MapView , Image) pattern first load 问题仍然会发生
<MapView.Marker>
<Image source={img_marker} />
</MapView.Marker>
所以采用了以下解决方案:技巧是在 redux 中保存当前选择的标记 id
class Map extends React.Component {
render() {
let {region, markers , markerClick} = this.props;
const normalMarkerImage = require('../../images/normal_marker.png');
const selectedMarkerImage = require('../../images/selected_marker.png');
return !isObjectEmpty(region) && !isObjectEmpty(markers) ? (
<MapView
style={styles.map}
showsUserLocation={true}
followUserLocation={true}
zoomEnabled={true}
region={region}
paddingAdjustmentBehavior={'automatic'}
showsIndoors={true}
showsIndoorLevelPicker={false}
showsTraffic={false}
toolbarEnabled={false}
loadingEnabled={true}
showsMyLocationButton={true}>
{markers && markers.length > 0
? markers.map((marker, i) => (
<MapView.Marker
coordinate={{
longitude: marker.loc.coordinates[0],
latitude: marker.loc.coordinates[1],
}}
key={`marker-${i}`}
style={{height: 20, width: 20}}
onPress={e => markerClick(e, marker)}
image={
this.props.selectedMarker === marker._id
? selectedMarkerImage
: normalMarkerImage
}
/>
))
: null}
</MapView>
) : null;
}
}
组件函数
markerClick = async (event, data) => {
this.props.dispatch(
setMarkerIconInRedux(this.state.popover.currentData._id)
);
};
动作
export const setMarkerIconInRedux = where => {
return {
type: 'SET_MARKER_ICON',
_id: where,
};
};
Redux
export const currentSelectedMarker = (state = {selectedMarker: ''}, action) =>
{
if (action.type === 'SET_MARKER_ICON') {
return {selectedMarker: action._id};
} else if (action.type === 'REMOVE_MARKER_ICON') {
return {selectedMarker: ''};
} else {
return state;
}
};
为此https://github.com/react-native-community/react-native-svg
使用SVG
<Marker
coordinate={{
longitude: lang,
latitude: lat,
}}
>
<View style={{
flexDirection: 'row', width: 100, height: 30,
backgroundColor: 'orange'
}}>
<Svg
width={40} height={30}>
<Image
href={url}
width={40}
height={30}
/>
</Svg>
<View
style={{
flexDirection: 'column'
}}
>
<Text
style={{
marginLeft: 2,
fontSize: 9,
color: '#ffffff',
fontWeight: 'bold',
textDecorationLine: 'underline'
}}
>{marker.title}</Text>
<Text
style={{
marginLeft: 2,
fontSize: 9,
color: '#ffffff',
fontWeight: 'bold',
textDecorationLine: 'underline'
}}
>{marker.description}</Text>
</View>
</View>
</Marker>
@Mahdi Bashirpour 解决方案对我有用。只是升级上面的答案。
如果我们从 'react-native-svg'
导入 'Image',其他图像将停止工作我的解决方案如下。
import {Image} from 'react-native'; // for other images in our render method.
import { Image as Imagesvg } from 'react-native-svg';
<Marker
coordinate={marker.latlng}
title={marker.title}
>
<View style={{ height: 90, width: 90, backgroundColor: 'orange' }}>
<Svg width={90} height={90}}>
<Imagesvg href={marker_g} width={90} height={90} /> // Local Images
<Imagesvg href={{uri:url}} width={90} height={90} /> //Server images
</Svg>
</View>
</Marker>
对标记图像使用'Imagesvg'。 它在 android 7 和 8 上为我工作。React 本机版本 '0.55.3'
我通过用 8 位伽玛整数图像替换 16 位伽玛整数图像解决了这个问题。可以在 Gimp 中完成,一旦导出图像 select 8bpc RGBA。
自 2019 年 10 月起,只要将 tracksViewChanges 设置为 true,图像就可以显示在标记中。我使用 FastImage,但一般的想法是将 tracksViewChanges 设置为 true,然后在图像加载后立即设置为 false,这样就不会有任何性能问题。
export const UserMapPin = props => {
const [trackView, setTrackView] = useState(true);
function changeTrackView() {
setTrackView(false);
}
return (
<Marker
tracksViewChanges={trackView}
coordinate={props.coordinates}>
<View style={styles.imageIconContainer}>
<FastImage
onLoadEnd={changeTrackView}
style={styles.someImageStyle}
source={{
uri: props.imageURI,
}}
resizeMode={FastImage.resizeMode.cover}
/>
</View>
</Marker>
);
};
就我而言,问题仅出在远程图像上,因此我通过 hack 解决了它。
我只是在文本组件中放置了一个零宽度的图像版本,在文本组件外部放置了一个版本。突然一切都解决了。
<Image
source={{ uri: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" }}
style={styles.companyLogoMarker}
resizeMode="cover"
/>
<Text style={styles.markerText}>
{names?.[0]?.value}
<Image
source={{ uri: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" }}
style={{width: 0, height: 0}}
resizeMode="cover"
/>
</Text>
在撰写此答案时,这是 [react native maps][1]
中的错误,自 2017 年以来未解决
在 <View>
中添加自定义标记组件
例如<View> your marker custom view </View>
。也许它会解决您的问题。