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
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 },
Most helpful comment
I make the listView position absolute and set zIndex, it's worked for me.
Example: