response-native-google-place-autocomplete приводит к непредсказуемым результатам при нажатии на первый элемент в списке - PullRequest
0 голосов
/ 07 января 2020

Я сейчас использую react-native-google-places-autocomplete в Formik и react-native-keyboard-aware-scroll-view. Но когда пользователь нажимает на первый элемент автоматически предложенного listView, это приводит к очень непредсказуемым результатам. Либо

1) не отвечает,
2) listView закрывается и адрес не выбирается, либо
3) listView остается открытым, но отправляет форму, даже если кнопка отправки формы не была нажата.

Как ни странно, когда нажимаются любые другие элементы в списке, кроме первого, это приводит к желаемым результатам.

   const onFocusAddressAutoComplete = () => {
        Animated.timing(googlePlacesAnimation, {
            toValue: 1,
            duration: 300,
        }).start(() => {
            setFocus(true)
        })
    }

    const onBlurAddressAutoComplete = () => {
        setFocus(false)
        Animated.timing(googlePlacesAnimation, {
            toValue: 0,
            duration: 300,
        }).start()
    }

    const animatedPictureHeightStyle = {
        height: pictureHeightInterpolation,
        width: pictureHeightInterpolation,
        opacity: googlePlacesOpacityInterpolation,
    }

    const animatedHeightStyle = {
        height: introHeightInterpolation,
        opacity: googlePlacesOpacityInterpolation,
    }

    const animatedButtonHeightStyle = {
        height: buttonHeightInterpolation,
        opacity: googlePlacesOpacityInterpolation,
    }

    const onFocusProps = () => {
        onFocusAddressAutoComplete()
    }

    const onBlurProps = (param, callback) => {
        callback(param)
        onBlurAddressAutoComplete()
    }

    const submitHandler = input => {
        //submit logic
    }

    return (
        <KeyboardAwareScrollView
            contentContainerStyle={styles.container}
            showsVerticalScrollIndicator={false}
            keyboardShouldPersistTaps={'always'}
            keyboardDismissMode={'on-drag'}
        >
            <Formik
                initialValues={{ address: '', introduction: '' }}
                onSubmit={submitHandler}
                validationSchema={yup.object().shape({
                    address: yup
                        .string()
                        .min(5)
                        .max(30)
                        .required(),
                    introduction: yup
                        .string()
                        .max(300),
                })}
            >
                {({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (

                    <FlatList
                        data={[
                            {
                                id: 1,
                                menu:
                                    <View style={styles.title}>
                                        <Text style={styles.titleText}>Sign up</Text>
                                        <TouchableHighlight
                                            onPress={() => navigation.navigate('Posting')}
                                            underlayColor={'rgba(0, 0, 0, 0)'}
                                            activeOpacity={0.2}
                                        >
                                            <Icon
                                                name="x"
                                                size={moderateScale(30)}
                                                color={"black"}
                                            />
                                        </TouchableHighlight>
                                    </View>
                            },
                            {
                                id: 2,
                                menu:
                                    <View style={styles.fieldset}>
                                        <Text style={styles.addressLegend}>
                                            <Text style={{ color: '#FF5D4E' }}>* </Text>
                                            Your location for rental pickups
                                        </Text>
                                        <View style={{ flex: 1, justifyContent: 'flex-start' }}>
                                            <GooglePlacesInput
                                                value={values.address}
                                                onBlur={() => onBlurProps('address', setFieldTouched)}
                                                onChangeTextFromFormik={handleChange('address')}
                                                onFocus={onFocusProps}
                                                focus={focus}
                                            />
                                        </View>
                                        {
                                            touched.address && errors.address &&
                                            <Text style={{ fontSize: 10, color: 'red' }}>{errors.address}</Text>
                                        }
                                    </View>
                            },
                            {
                                id: 3,
                                menu:
                                    <Animated.View style={[styles.buttonContainer, animatedButtonHeightStyle]} >
                                        <TouchableHighlight
                                            disabled={!isValid || loading || called || signupLoading}
                                            onPress={handleSubmit}
                                            style={[styles.button, isSigninPressed && { borderColor: '#EAC0C0' }]}
                                            underlayColor={'#FF5D4E'}
                                            activeOpacity={0.2}
                                            onShowUnderlay={() => signinPressed(true)}
                                            onHideUnderlay={() => signinPressed(false)}
                                        >
                                            <Text style={[styles.buttonText, isSigninPressed && { color: 'white' }]}>Submit</Text>
                                        </TouchableHighlight>
                                    </Animated.View>
                            }
                        ]}
                        renderItem={renderItem}
                        scrollEnabled={false}
                        keyExtractor={item => item.id.toString()}
                        keyboardShouldPersistTaps={'always'}
                    />

                )
                }
            </Formik >
        </KeyboardAwareScrollView>
    )

И компонент GooglePlacesIput:

export default GooglePlacesInput = ({
    onFocus,
    onBlur,
    onChangeTextFromFormik,
    value,
    addressRef,
    focus,
}) => {
    return (
        <GooglePlacesAutocomplete
            ref={addressRef}
            placeholder='Search'
            minLength={1} // 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={focus}   // true/false/undefined
            fetchDetails={true}
            textContentType={'fullStreetAddress'}
            autoCapitalize={'words'}
            selectionColor={'red'}
            clearButtonMode={'always'}
            autoCompleteType={'street-address'}
            // blurOnSubmit={false}
            renderDescription={row => row.description} // custom description render
            onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
                // const lat = JSON.stringify(details.geometry.location.lat)
                // const lng = JSON.stringify(details.geometry.location.lng)
                const { description, types } = data && data
                const address = {
                    lat: details.geometry.location.lat,
                    lng: details.geometry.location.lng,
                    location: description,
                    addressType: types,
                }
                onChangeTextFromFormik(address)
            }}
            textInputProps={{
                onChangeText: (text) => { },
                onFocus,
                onBlur,
            }}
            value={value}
            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: '', // default: 'geocode'
                location: '43.70011, -79.4163',
                radius: '100000', //100 km
                components: 'country:ca',
                strictbounds: true,
            }}
            styles={{
                container: {
                    width: '100%',
                },
                listView: {
                    position: 'absolute',
                    top: 70,
                    left: 10,
                    right: 10,
                    backgroundColor: 'transparent',
                    borderRadius: 5,
                    flex: 1,
                    elevation: 3,
                    zIndex: 1000,
                    margin: 0,
                },
                textInputContainer: {
                    backgroundColor: 'transparent',
                    marginTop: 0,
                    width: '100%',
                    padding: 0,
                    borderTopWidth: 0,
                    borderBottomWidth: 0,
                },
                textInput: {
                    backgroundColor: '#F9F5F4',
                    borderRadius: 50,
                    width: "100%",
                    height: height / 15,
                    marginLeft: 0,
                    marginRight: 0,
                    marginTop: 0,
                    paddingLeft: 30,
                    fontSize: 15,
                },
                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={{ fields: 'geometry', }}
            // 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={() => { }}
        />
    )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...