Issue
I'm trying to use the react-native-google-places-autocomplete
library within my React Native app, but I'm having an issue clicking on the suggested list. Whenever I click on the Google suggested address, the list disappears and onPress
doesn't grab the address. If I use the library in a component by itself without the parent components, it works perfectly fine, but only when I place the component within keyboardavoidingview
or KeyboardAwareScrollView
, it does not work:
This GooglePlacesInput.js component is just the standard library from the original repository:
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
keyboardAppearance={'light'} // Can be left out for default keyboardAppearance https://facebook.github.io/react-native/docs/textinput.html#keyboardappearance
listViewDisplayed={false} // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);
}}
textInputProps={{
onBlur,
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: googleAPIKeyForAutocomplete,
language: 'en', // language of the results
region: "CA",
// types: '(cities)' // default: 'geocode'
types: '',
}}
styles={{
listView: {
position: 'absolute',
top: 60,
left: 10,
right: 10,
backgroundColor: 'white',
borderRadius: 5,
flex: 1,
elevation: 3,
zIndex: 100,
},
textInputContainer: {
backgroundColor: 'transparent',
margin: 0,
width: '100%',
padding: 0,
borderTopWidth: 0,
borderBottomWidth: 0
},
textInput: {
backgroundColor: '#F9F5F4',
borderRadius: 50,
width: "100%",
height: height / 15,
padding: 20,
},
description: {
// color: '#ac879a',
fontWeight: '300'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
type: 'food'
}}
GooglePlacesDetailsQuery={{
// available options for GooglePlacesDetails API : https://developers.google.com/places/web-service/details
fields: 'formatted_address',
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={[]}
enablePoweredByContainer={false}
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
renderLeftButton={() => { }}
renderRightButton={() => { }}
/>
I'm using Formik
for its parent component Form.js
:
<View style={styles.container} >
<Formik
initialValues={initialValues}
onSubmit={(value, action) => submitHandler(value, action)}
validationSchema={yup.object().shape({
address: yup
.string()
.min(5)
.required(),
})}
>
{({
values,
handleChange,
errors,
setFieldTouched,
touched,
isValid,
handleSubmit,
resetForm,
isSubmitting,
}) => (
<View style={styles.form}>
<Animated.View
style={[styles.fieldset, addressStyle]}
onLayout={e => {
if (addressHeight !== e.nativeEvent.layout.y) {
setAddressHeight(e.nativeEvent.layout.y)
}
}}
>
<Text style={{ marginLeft: 40, marginVertical: 5 }}>
<Text style={{ color: '#FF5D4E' }}>* </Text>
Address
</Text>
<View style={styles.autoComplete}>
<GooglePlacesInput
onBlur={() => onBlurProps('address', setFieldTouched)}
/>
</View>
</Animated.View>
{touched.address && errors.address &&
<Animated.Text style={{ fontSize: 10, color: 'red' }}>{errors.address}</Animated.Text>
}
<TouchableOpacity
disabled={!isValid || loading || isSubmitting}
onPress={handleSubmit}
style={styles.button}
>
<Text style={styles.buttonText}>Submit</Text>
</TouchableOpacity>
</View>
)}
</Formik>
</View>
handleChange
still has to be passed, but I want to first figure out the onPress
situation first.
And finally, the most parent component:
<KeyboardAwareScrollView>
<SafeAreaView style={styles.container} >
<ScrollView
keyboardShouldPersistTaps={'always'}
contentContainerStyle={styles.container}
style={{ flexGrow: 1 }}
showsVerticalScrollIndicator={false}
onLayout={e => {
if (heightPosition !== e.nativeEvent.layout.y) {
setHeightPosition(e.nativeEvent.layout.y)
}
}}
>
<View style={styles.form}>
<Form
submitHandler={submitHandler}
loading={loading}
heightPosition={heightPosition}
/>
</View>
</ ScrollView>
</SafeAreaView>
</KeyboardAwareScrollView>
Solution
Please include keyboardShouldPersistTaps='always' in your parent ScrollView JSX
and listViewDisplayed={false} as per the documentation
Answered By - Rahul Shakya
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.