React-native-google-places-autocomplete: ListView doesnt overdraw other component and is invisible

Created on 16 Sep 2018  路  7Comments  路  Source: FaridSafi/react-native-google-places-autocomplete

Hi guys. Have trouble with overdrawing (zIndex or so) with suggested google places listview.
Everything works well but that listView dont want to render properly.
Expected: to render listView over every other component.
Actual behavior: listView hides on other components.

Code of components where problem is:

import React, { Component } from 'react'
import { Platform, Navigator, Text, 
    View, StyleSheet, TextInput, 
    TouchableOpacity, Dimensions, ListView } from 'react-native'
import RestaurantSearch from './RestaurantSearch'
import Search from 'react-native-search-box'
import SpaceComponent from '../cell/SpaceComponent'
import Geocoder from 'react-native-geocoder'
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete'


const { width, height } = Dimensions.get('window')

const restaurantData = [
    { text: 'American' },
    { text: 'Breakfast & Brunch' },
    { text: 'Burgers' },
    { text: 'Chinese' },
    { text: 'Indian' },
    { text: 'Italian' },
    { text: 'Japanese' },
    { text: 'Korean' },
    { text: 'Mexican' },
    { text: 'Pizza' },
    { text: 'Sandwiches' },
    { text: 'Seafood' },
    { text: 'Steakhouse' },
    { text: 'Sushi' },
    { text: 'Thai' },
    { text: 'Vietnamese' }
];

const GEO_API_KEY = 'AIza... haha..'

const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });

class RestaurantNav extends Component {
    constructor(props) {
        super(props);
        this.state = {
            latitude: '', 
            longitude: '',
            restaurantName: '',
            locationName: '',
            isSuggestionList: false,
            isLocationMenu: false,
            isdropdown: false,
            str_restaurant: 'Restaurant',
            str_searchRestaurant: '',
            params: '',
            suggestedArray: [],
            dataSource: ds.cloneWithRows([]),
        }
        console.log(props)
        this.getPos = this.getPos.bind(this)
    }

    getPos(){
        let that = this
        navigator.geolocation.getCurrentPosition(
            (position) => {
                that.setState({
                    latitude: Number(position.coords.latitude.toFixed(8)),
                    longitude: Number(position.coords.longitude.toFixed(8)),
                })

            }
        )          
    }

    componentWillMount() {

    }

    componentDidMount() {
        this.getPos()
    }

    loadListView() {

    }

    renderRow(rowData, sectionID, rowID, highlightRow) {
        return (
            <TouchableOpacity onPress={() => {
                this.pressRow(rowID);
            }}>
                <View style={styles.cell}>
                    <Text style={styles.celltext}>
                        {rowData}
                    </Text>
                </View>
            </TouchableOpacity>
        );
    }

    renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
        return (
            <View
                key={`${sectionID}-${rowID}`}
                style={{
                    height: 1,
                    backgroundColor: '#CCCCCC',
                }}
            />
        );
    }

    pressRow(rowID) {
        this.setState({ 
            str_searchRestaurant: this.state.suggestedArray[rowID].text,
            isSuggestionList: false 
        })
    }

    _onPressSearch() { 
            if (this.state.str_searchRestaurant !== '') {
                var searchText = this.state.str_searchRestaurant
                var params = '&query=' + searchText + '&rank=' + 'distance' + '&price=' + ''
                this.setState({ 
                    params: params,
                    dataSource: ds.cloneWithRows(this.state.suggestedArray.map(function (element) {
                        return element.text
                    }))
                }) 
            } else {
                this._onPressSearch()
            }
    }

    showDropDown() {
        if (this.state.isdropdown == true) {
            return (
                <View style={styles.dropView}>
                    <TouchableOpacity onPress={this.restaurantTag}>
                        <Text style={{ color: 'white', height: 20 }}>Restaurant</Text>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={this.dishTag}>
                        <Text style={{ color: 'white', marginTop: 7 }}>Dish</Text>
                    </TouchableOpacity>
                </View>
            );
        } else {
            return (
                <View></View>
            )
        }
    }

    _onPressRestaurant = () => {
        this.setState({ isdropdown: !this.state.isdropdown })
    }

    restaurantTag = () => {
        this.setState({
            str_restaurant: 'Restaurant',
            str_searchRestaurant: 'Search Restaurants',
            isdropdown: !this.state.isdropdown,
        })
    }
    dishTag = () => {
        this.setState({
            str_restaurant: 'Dish',
            str_searchRestaurant: 'Dish',
            isdropdown: !this.state.isdropdown,
        })
    }

    findData() {
        if (this.state.str_searchRestaurant === '') {
            return [];
        }
        const regex = new RegExp(`${this.state.str_searchRestaurant.toString().trim()}`, 'i');
        return restaurantData.filter(data => data.text.search(regex) >= 0);
    }

    render() {

        const restaurantData = this.findData();
        const comp = (a, b) => a.toLowerCase().trim() === b.toLowerCase().trim();

        return (
            <View style={styles.wrapper}>
                <View style={styles.navview}>
                    <SpaceComponent topSpace={25} />
                      <Text style={{ color: 'white', fontSize: 18, fontWeight: 'bold' }}>Restaurant Search</Text>
                    <SpaceComponent bottomSpace={10} />
                </View>
                <View style={styles.menuview}>
                    <View style={{ height: 40, flexDirection: 'row', alignItems: 'center' }}>

                        <TouchableOpacity onPress={this._onPressRestaurant}>
                            <Text style={{ color: 'white', paddingLeft: 10, paddingRight: 10, textAlign: 'center', width: 100 }}>{this.state.str_restaurant}</Text>
                        </TouchableOpacity>
                        <View style={{ height: 40, position: 'relative', width: width - 100 }}>
                            <Search
                                ref='SearchBar'
                                keyword={this.state.str_searchRestaurant}
                                backgroundColor='transparent'
                                titleCancelColor='white'
                                onChangeText={(text) => {
                                    this.setState({ 
                                        str_searchRestaurant: text,
                                        suggestedArray: this.findData(), 
                                        isSuggestionList: true 
                                    })
                                    this._onPressSearch()
                                    // this.loadListView()
                                }}
                                onFocus={() => {
                                    this.setState({
                                        isLocationMenu: true
                                    })
                                }}
                                onCancel={() => {
                                    this.setState({ 
                                        isLocationMenu: false,
                                        isSuggestionList: false 
                                    })
                                }}
                                onSearch={() => {
                                    this._onPressSearch()
                                }}
                                onBlur={() => {
                                    this.setState({
                                        isSuggestionList: false
                                    })
                                }}
                            />
                        </View>
                    </View>
                    {
                        (this.state.isLocationMenu) ?
                            <View style={{ height: 40, flexDirection: 'row', alignItems: 'center', marginTop: -5 }}>
                                {/* <Text style={{ color: 'white', paddingLeft: 10, paddingRight: 10, textAlign: 'center', width: 100 }}>{this.state.str_restaurant}</Text> */}
                                <Text style={{ color: 'white', paddingLeft: 10, paddingRight: 10, textAlign: 'center', width: 100 }}>Location</Text> 
                                <View style={{ height: '100%', position: 'absolute', width: width - 100, right: 0 }}>
                                {/* <View style={{ height: 40, position: 'absolute', right: 10, left: 90 }}> */}

                                    <GooglePlacesAutocomplete
                                        placeholder='Enter Location'
                                        minLength={1}
                                        autoFocus={false}
                                        returnKeyType={'search'}
                                        onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
                                            console.log(data, details);
                                        }}
                                        listViewDisplayed={true}
                                        getDefaultValue={() => 'New York'}
                                        query={{
                                            // available options: https://developers.google.com/places/web-service/autocomplete
                                            key: GEO_API_KEY,
                                            language: 'en', // language of the results
                                             // default: 'geocode'
                                        }}
                                        nearbyPlacesAPI='GooglePlacesSearch'
                                        GooglePlacesSearchQuery={{
                                            // available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
                                            rankby: 'distance',
                                            types: 'food'
                                        }}
                                        styles={{
                                            container: {
                                                zIndex: 9999,
                                                position: 'absolute',
                                                width: '100%'
                                            },
                                            textInputContainer: {
                                                backgroundColor: 'rgba(0,0,0,0)',
                                                borderTopWidth: 0,
                                                borderBottomWidth: 0,
                                                height: 200,
                                            },
                                            textInput: {
                                                marginLeft: 5,
                                                marginRight: 5,
                                                color: '#5d5d5d',
                                                fontSize: 12,
                                                height: 30,
                                            },
                                            predefinedPlacesDescription: {
                                                color: '#1faadb'
                                            },
                                            listView: {
                                                flex: 1,
                                                position: 'absolute',
                                                top: 40,
                                                backgroundColor: 'red',
                                                marginHorizontal: 5,
                                                width: width,
                                                minHeight: 160
                                            },
                                            row: {
                                                height: 40
                                            },
                                            poweredContainer: {
                                                display: 'none'
                                            },
                                            powered: {
                                                display: 'none'
                                            }
                                        }}
                                    />
                                </View>
                            </View>
                            :
                            null
                    }
                </View>
                <View style={styles.suggestionListViewContainer}>
                    {
                        (this.state.isSuggestionList) ?
                            <ListView
                                removeClippedSubviews={false}
                                dataSource={this.state.dataSource}
                                renderRow={this.renderRow.bind(this)}
                                renderSeparator={this.renderSeparator.bind(this)}
                                enableEmptySections={true}
                            />
                            :
                            null
                    }
                </View>
                <RestaurantSearch userId={this.props.userId} navigation={this.props.navigation} params1={this.state.params} />
                {this.showDropDown()}
            </View>
        )
    }
}

const styles = StyleSheet.create({
    wrapper: {
        flex: 1,
        backgroundColor: 'white',
    },
    navview: {
        backgroundColor: '#652D6C',
        width: width,
        height: Platform.OS === 'ios'? null : 50,
        justifyContent: 'center',
        alignItems: 'center'
    },
    menuview: {
        width: width,
        //   backgroundColor:'lightgray',
        backgroundColor: '#652D6C',
    },
    dropView: {
        width: 100,
        height: 60,
        backgroundColor: '#652D6C',
        position: 'absolute',
        left: 0,
        top: 90,
        justifyContent: 'center',
        alignItems: 'center',
    },
    itemText: {
        fontSize: 15,
        margin: 2
    },
    cell: {
        height: 30,
        backgroundColor: '#EEEEEE',
        paddingHorizontal: 20,
        justifyContent: 'center',
    },
    suggestionListViewContainer: {
        // flex: 1,
        // position: 'absolute',
        // right: 74,
        // left: 95,
        // top: 90,
        borderWidth: 0,
        borderRadius: 3,
        borderColor: '#DDDDDD',
        // opacity: 1,
        // zIndex: 100
    }
});

export default RestaurantNav

Most helpful comment

I make the listView position absolute and set zIndex, it's worked for me.

Example:

listView: {
       position: 'absolute',
       zIndex: 9999,
       top: 40
},
row: {
        backgroundColor: 'white'
},

All 7 comments

I make the listView position absolute and set zIndex, it's worked for me.

Example:

listView: {
       position: 'absolute',
       zIndex: 9999,
       top: 40
},
row: {
        backgroundColor: 'white'
},

unable to touch listView, because of absolute position

thanks @munonn430

unable to touch listView, because of absolute position

Did you get any solution?

If you still have this issue try to give other components negative zIndex.

I just ran into this. I had the Library wrapped in a SafeView From RN and that was blocking the listview from showing. Feel free to drop a PR to fix.

I ended up setting the listView to absolute position and giving the other fields below it a negate zIndex

<GooglePlacesAutocomplete .... styles={{ ..... listView: styles.listView, }} />

listView: { position: 'absolute', top: 40, borderColor: Colors.GreyMid2, borderLeftWidth: 1, borderRightWidth: 1, borderBottomWidth: 1, borderBottomLeftRadius: 4, borderBottomRightRadius: 4, },

<View style={styles.field}> .... </View>

field: { width: '100%', marginBottom: 6, zIndex: -1 },

Was this page helpful?
0 / 5 - 0 ratings

Related issues

quandevelopment picture quandevelopment  路  4Comments

nikohosn picture nikohosn  路  3Comments

yasirdev picture yasirdev  路  3Comments

tezahzulueta picture tezahzulueta  路  3Comments

aymkin picture aymkin  路  4Comments