MapView исчезает, когда вызывается animateToRegion (), а маркеры местоположения не отображаются до тех пор, пока не будет вызвана animateToRegion (). - PullRequest
0 голосов
/ 07 февраля 2019

У меня проблема с получением карты в моем приложении, чтобы ее маркеры загружались при первом рендере.Предполагается, что маркеры соответствуют строительным картам в виде прокрутки.Файл App.js, который вызывает CustomMapView, содержит жестко закодированные фиктивные данные в виде массива из 5 объектов Building {title, description, lat, long}, которые он передает CustomMapView, а затем CustomMapView передает данные остальным своим дочерним элементам (вкод ниже)

Когда приложение загружается впервые, оно выглядит следующим образом:

Here

Затем при переходе к следующему указателю появляются маркеры (и анимируются), но затем карта исчезает:

Here

Это мой первый проект React Native, и я несколько дней пытался понять, что маркер не рендерит, и проблема исчезновения карты.Я в основном пытаюсь сделать карту с видом прокрутки, которая содержит здания, и когда вы прокручиваете эту «Карту здания», карта оживляет здание.Любая помощь будет высоко ценится.Спасибо!

class CustomMapView extends Component {

/*
    this.lastLoadedIndex
    this.animation
    this.state
    this.mapView
    this.interpolations
    this.regionTimeout
 */

constructor(props) {
    super(props);
    this.lastLoadedIndex = 0;
    this.animation = new Animated.Value(0);
    this.state = {
        buildings: this.props.buildings,
        region: this.props.initialRegion,
    };
}

componentDidMount() {
    this.beginAnimatingMapToMatchSelectedBuildingCard();
}

render() {

    this.interpolations = this.state.buildings.map((building, index) => {
        const inputRange = [(index - 1) * CARD_WIDTH, index * CARD_WIDTH, ((index + 1) * CARD_WIDTH)];

        const scale = this.animation.interpolate({
            inputRange,
            outputRange: [INACTIVE_MARKER_RADIUS_SCALE, ACTIVE__MARKER_RADIUS_SCALE, INACTIVE_MARKER_RADIUS_SCALE],
            extrapolate: "clamp",
        });

        const opacity = this.animation.interpolate({
            inputRange,
            outputRange: [INACTIVE_MARKER_OPACITY, ACTIVE_MARKER_OPACITY, INACTIVE_MARKER_OPACITY],
            extrapolate: "clamp",
        });
        return { scale, opacity };
    });


    return (
        <View style={StJamesMapViewStyle.container}>
            <MapWithBuildingMarkers root={this} interpolations={this.interpolations} region={this.state.region} buildings={this.state.buildings} />
            <BuildingCardSelectorView root={this} buildings={this.state.buildings}/>
        </View>
    );
}

beginAnimatingMapToMatchSelectedBuildingCard() {
    this.animation.addListener(({value}) => {
        let index = Math.floor(value / CARD_WIDTH + SCROLL_OFFSET);

        if (index < 0)
            index = 0;

        else if (index >= this.state.buildings.length)
            index = this.state.buildings.length - 1;


        clearTimeout(this.regionTimeout);

        this.regionTimeout = setTimeout(() => {

            if (this.lastLoadedIndex === index)
                return;

            this.lastLoadedIndex = index;
            const coordinateToBeLoaded = this.state.buildings[index].coordinate;
            const region = {
                latitude: coordinateToBeLoaded.latitude,
                longitude: coordinateToBeLoaded.longitude,
                latitudeDelta: this.state.region.latitudeDelta,
                longitudeDelta: this.state.region.longitudeDelta
            };
            this.mapView.animateToRegion(region, DURATION_AFTER_BUILDING_CARD_IS_SELECTED_TO_START_ANIMATING);
            console.log(region);
        }, DURATION_TO_ANIMATE_TO_REGION);
    });

}


}

class MapWithBuildingMarkers extends Component {

render() {
    const root = this.props.root;
    const buildings = this.props.buildings;
    const interpolations = this.props.interpolations;

    return (
        <MapView ref={mapView => root.mapView = mapView} //When we animateToRegion we render MapView which has Building Markers as its children
                 initialRegion={this.props.region}
                 style={StJamesMapViewStyle.container}>

            {buildings.map((building, index) => <BuildingMarker key={index} index={index} building={building} interpolations={interpolations}/>)}

        </MapView>);
}
}


class BuildingMarker extends Component {

render() {

    const scaleStyle = {transform: [{scale: this.props.interpolations[this.props.index].scale}]};
    const opacityStyle = {opacity: this.props.interpolations[this.props.index].opacity};

    return (
    <MapView.Marker coordinate={this.props.building.coordinate}>
            <AnimatedView style={[StJamesMapViewStyle.markerWrap, opacityStyle]}>
                <AnimatedView style={[StJamesMapViewStyle.ring, scaleStyle]}/>
                    <View style={StJamesMapViewStyle.marker} />
            </AnimatedView>
    </MapView.Marker>);
}
}


class BuildingCardSelectorView extends Component {

render() {

    const root = this.props.root;

    const scrollHandler = Animated.event([{
        nativeEvent: {
            contentOffset: {
                x: root.animation,
            }
        }}],
        { useNativeDriver: true }
    );

    return (
        <Animated.ScrollView horizontal
                             scrollEventThrottle={1}
                             showsHorizontalScrollIndicator={false}
                             snapToInterval={CARD_WIDTH}
                             onScroll={scrollHandler}
                             style={StJamesMapViewStyle.scrollView}
                             contentContainerStyle={StJamesMapViewStyle.endPadding}>

            {this.props.buildings.map((building, index) => <BuildingCard key={index}
                                                                         index={index}
                                                                         building={building}/>)}
        </Animated.ScrollView>
    );
}
}


class BuildingCard extends Component {

render() {
    return (
        <View style={StJamesMapViewStyle.card}>
            <Image source={this.props.building.imageURL} style={StJamesMapViewStyle.cardImage} resizeMode="cover"/>
            <View style={StJamesMapViewStyle.textContent}>
                <Text numberOfLines={1}> {this.props.building.title} </Text>
                <Text numberOfLines={1}> {this.props.building.description} </Text>
            </View>
        </View>
    );
}
}
...