React Native - API автозаполнения Google - PullRequest
0 голосов
/ 04 мая 2019

Моя проблема в том, что Text результат описания перекрывается друг с другом.Я не знаю, если это ошибка, я просто не могу ее решить.Я попробовал что-нибудь про стили, но ничего не работает.Мне нужна помощь от других с другой точки зрения.Спасибо, что нашли время, чтобы прочитать это.

Изображение перекрывающихся текстов:

enter image description here

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

Изображение с предупреждением key prop: enter image description here

Вотмои коды:

async onChangeDestination(destination) {
this.setState({ destination });
const apiUrl = `https://maps.googleapis.com/maps/api/place/autocomplete/json?key=${apiKey}
  &input=${destination}&location=${this.state.focusedLocation.latitude}, 
  ${this.state.focusedLocation.longitude
}&radius=2000`;
try {
  const result = await fetch(apiUrl);
  const json = await result.json();
  console.log(json);
  this.setState({
    predictions: json.predictions
  });
} catch (err) {
  console.log(err)
}
}

render() {
//For Prediction
const predictions = this.state.predictions.map(prediction => (
  <View style={styles.descriptionContainer}>
    <Text key={prediction.id} style={styles.descriptionText}>{prediction.description}</Text>
  </View>
));
//For Marker
let marker = null;
if(this.state.locationChosen) {
  marker = <MapView.Marker coordinate={this.state.markerPosition}/>
}
return(
  <View style={styles.container}>
    {/* <StatusBar backgroundColor={'transparent'} translucent={true}/> */}
    <MapView
      style={styles.map}
      initialRegion={this.state.focusedLocation}
      onPress={this.pickLocationHandler}
      showsUserLocation={true}
      ref={ref => this.map = ref} //For animating map movement
    >
      {marker}
    </MapView>
    {/* <TouchableOpacity onPress={this.getLocationHandler} style={styles.iconContainer}>
      <Icon name="md-locate" size={30} color="blue"/>
    </TouchableOpacity> */}
    <TextInput 
      placeholder="Search for an event or place!"
      style={styles.destinationInput}
      onChangeText={destination => {
        this.setState({destination});
        this.onChangeDestinationDebounced(destination)
      }}
      value={this.state.destination}
    />
    {predictions}
  </View>
);
} 

const styles = StyleSheet.create({
container: {
  zIndex: -1,
  alignItems: 'center',
},
map: {
  height: '100%',
  width: '100%'
},
iconContainer: {
  position: 'absolute',
  top: 60,
  right: 15,
  zIndex: 1
},
destinationInput: {
  position: 'absolute',
  zIndex: 10,
  width: '97%',
  top: 15,
  backgroundColor: 'white',
  borderRadius: 8,
  padding: 8
},
descriptionText: {
  color: 'black',
  position: 'absolute',
  zIndex: 10,
  top: 60,
},
descriptionContainer: {
  zIndex: 2,
  position: 'absolute',
  top: 20,
  height: Dimensions.get('window').height,
  width: Dimensions.get('window').width,
  justifyContent: 'space-between'
}
})

1 Ответ

2 голосов
/ 04 мая 2019

Так что я не смог запустить код, однако ваш стиль descriptionText имеет положение: «абсолютный». Поэтому поведение, которое вы видите, является ожидаемым, поскольку каждый текст находится в одной и той же «абсолютной» позиции. Удаление этого должно дать вам желаемый результат.

Предупреждение о ключе выдается, так как ваш descriptionContainer View является корневым элементом в функции карты, поэтому он должен иметь ключ. Надеюсь, это поможет, обновленный исходный код ниже с небольшой оговоркой, что я не смог его протестировать.

async onChangeDestination(destination) {
this.setState({ destination });
const apiUrl = `https://maps.googleapis.com/maps/api/place/autocomplete/json?key=${apiKey}
  &input=${destination}&location=${this.state.focusedLocation.latitude}, 
  ${this.state.focusedLocation.longitude
}&radius=2000`;
try {
  const result = await fetch(apiUrl);
  const json = await result.json();
  console.log(json);
  this.setState({
    predictions: json.predictions
  });
} catch (err) {
  console.log(err)
}
}

render() {
//For Prediction
const predictions = this.state.predictions.map(prediction => (
  <Text key={prediction.id} style={styles.descriptionText}>{prediction.description}</Text>
));
//For Marker
let marker = null;
if(this.state.locationChosen) {
  marker = <MapView.Marker coordinate={this.state.markerPosition}/>
}
return(
  <View style={styles.container}>
    {/* <StatusBar backgroundColor={'transparent'} translucent={true}/> */}
    <MapView
      style={styles.map}
      initialRegion={this.state.focusedLocation}
      onPress={this.pickLocationHandler}
      showsUserLocation={true}
      ref={ref => this.map = ref} //For animating map movement
    >
      {marker}
    </MapView>
    {/* <TouchableOpacity onPress={this.getLocationHandler} style={styles.iconContainer}>
      <Icon name="md-locate" size={30} color="blue"/>
    </TouchableOpacity> */}
    <TextInput 
      placeholder="Search for an event or place!"
      style={styles.destinationInput}
      onChangeText={destination => {
        this.setState({destination});
        this.onChangeDestinationDebounced(destination)
      }}
      value={this.state.destination}
    />
    {this.state.predictions && this.state.predictions.length > 0 && (
       <View style={styles.descriptionContainer}>{predictions}</View>
    )}
  </View>
);
} 

const styles = StyleSheet.create({
container: {
  zIndex: -1,
  alignItems: 'center',
},
map: {
  height: '100%',
  width: '100%'
},
iconContainer: {
  position: 'absolute',
  top: 60,
  right: 15,
  zIndex: 1
},
destinationInput: {
  position: 'absolute',
  zIndex: 10,
  width: '97%',
  top: 15,
  backgroundColor: 'white',
  borderRadius: 8,
  padding: 8
},
descriptionText: {
  color: 'black',
},
descriptionContainer: {
  zIndex: 2,
  position: 'absolute',
  top: 20,
  height: Dimensions.get('window').height,
  width: Dimensions.get('window').width,
}
})
...