React Native 的 OnPress Google Places Autocomplete 由于其父组件而无法工作
OnPress for React Native Google Places Autocomplete doesn't work due to its parent components
我正在尝试在我的 React Native 应用程序中使用 react-native-google-places-autocomplete
库,但我在单击建议列表时遇到了问题。每当我单击 Google 建议的地址时,列表就会消失,并且 onPress
不会获取地址。如果我在没有父组件的组件中单独使用库,它工作得很好,但只有当我将组件放在 keyboardavoidingview
或 KeyboardAwareScrollView
内时,它才不起作用:
这个 GooglePlacesInput.js 组件只是来自原始 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={() => { }}
/>
我正在使用 Formik
作为其父组件 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
还是要通过的,不过我想先搞清楚onPress
的情况。
最后,最父组件:
<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>
请在您的父级 ScrollView JSX 中包含 keyboardShouldPersistTaps='always'
和 listViewDisplayed={false} 根据文档
包括这个 属性 keepResultsAfterBlur={true}
.
如果您需要将此组件包含在 ScrolView
或 FlatList
中,请记住将 keyboardShouldPersistTaps='handled'
属性应用于所有祖先 ScrollView
或 FlatList
根据文档。 Documentation Link
我正在尝试在我的 React Native 应用程序中使用 react-native-google-places-autocomplete
库,但我在单击建议列表时遇到了问题。每当我单击 Google 建议的地址时,列表就会消失,并且 onPress
不会获取地址。如果我在没有父组件的组件中单独使用库,它工作得很好,但只有当我将组件放在 keyboardavoidingview
或 KeyboardAwareScrollView
内时,它才不起作用:
这个 GooglePlacesInput.js 组件只是来自原始 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={() => { }}
/>
我正在使用 Formik
作为其父组件 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
还是要通过的,不过我想先搞清楚onPress
的情况。
最后,最父组件:
<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>
请在您的父级 ScrollView JSX 中包含 keyboardShouldPersistTaps='always'
和 listViewDisplayed={false} 根据文档
包括这个 属性 keepResultsAfterBlur={true}
.
如果您需要将此组件包含在 ScrolView
或 FlatList
中,请记住将 keyboardShouldPersistTaps='handled'
属性应用于所有祖先 ScrollView
或 FlatList
根据文档。 Documentation Link