React Native Maps: Изображение маркеров не отображается с помощью Custom Marker в адаптивных картах

Я использую react-native-maps но столкнулся с проблемой, которая после долгих поисков без ответа заставляет меня спросить об этом здесь. Я пытаюсь использовать пользовательский маркер для маркера на карте, как показано на следующем рисунке.

enter image description here

  • когда я искал, я обнаружил, что необходимо использовать Custom Marker для выполнения дизайна производителя, затем я создал компонент 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, он работает нормально и показывает изображение, но когда я использую его как пользовательский вид маркера, он не показывает изображение

enter image description here

Я не знаю, почему он не может отрисовать изображение с помощью пользовательского маркера в Android. и вот мой код, где я использую карту, маркеры и пользовательский класс маркеров

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>

любая помощь будет оценена.

Ответ 1

Используйте SVG для этого https://github.com/react-native-community/react-native-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>

Ответ 2

Моя проблема была решена прямо сейчас.

Надеюсь, ваша проблема будет решена.

Это мой чистый код:

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>
        );
    }
}

Ответ 3

У меня такая же проблема.

При первой загрузке приложения изображение не отображается, но для последующей загрузки эта проблема разрешена и отображается изображение.

Как только после загрузки изображения вызовите 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

Ответ 4

Решение @Mahdi Bashirpour работает для меня. просто обновление выше ответа.

Другие изображения перестают работать, если мы импортируем 'Image' из 'response-native-svg'

Мое решение ниже.

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. Реагирует на родную версию '0.55.3'

Ответ 5

Это еще один пример

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>
    )
  }
}

Ответ 6

У меня была такая же проблема, из сообщения github

используя ниже (MapView, Image), проблема с первой загрузкой все равно будет

<MapView.Marker>
    <Image source={img_marker} />
</MapView.Marker>

поэтому принято ниже решение: трюк заключается в том, чтобы сохранить текущий выбранный идентификатор маркера в сокращении

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;
    }
};

Ответ 7

Я решил эту проблему, заменив 16-разрядное целочисленное гамма-изображение на 8-разрядное целочисленное гамма-изображение. Это можно сделать в Gimp, после экспорта изображения выберите 8bpc RGBA.

Ответ 8

Большинство из этих примеров вводят изображение, обернутое внутри маркера, вместо того, чтобы использовать его в качестве опоры для маркера (согласно документам). Есть причина для этого?