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 不会获取地址。如果我在没有父组件的组件中单独使用库,它工作得很好,但只有当我将组件放在 keyboardavoidingviewKeyboardAwareScrollView 内时,它才不起作用:

这个 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}.

如果您需要将此组件包含在 ScrolViewFlatList 中,请记住将 keyboardShouldPersistTaps='handled' 属性应用于所有祖先 ScrollViewFlatList根据文档。 Documentation Link