Please have a look at my Expo Snack.
Dropdown items are touchable in iOS but not in Android. Fixed container\'s height (grey box) causes this issue but I need to kee
I changed your code, check this : Snack link
That's solve your problem but you can update your react-native version to include this commit that adds support for the overflow
style property on React Native for Android.
It seems like when dropdown expands, it flows outside of view because you have given fixed height.
so for workaround you can use minHeight
property instead of height
.
this will make sure that at least you get your minimum height and if needed it can use more height, like when you are expanding dropdown.
correction is given below,
dropdownContainer: {
width:340,
minHeight:115,// changed this from height:115
...
...
},
I wouldn't use a dependency instead I would manage it myself.
DropDown
that covers the whole screen with an absolute position (so that it doesn't affect the position of other elements on the screen). This component is invisible when inactive. DropDown
component.DropDown
component re-renders and a small menu is displayed in close proximity to the original button that was pressed. Here is the code, but I have also put it in a snack for you to play with https://snack.expo.io/@andypandy/dropdownmenu
There are lots of possibilities that you could do with this. You could pass in children as props, you could hook it in to redux and set it at the root of your app so that it can be used anywhere. The styles can easily be changed. It really is quite flexible in what you can do with it. I have used this in many applications that are currently live in both app stores.
import React from 'react';
import {
Text,
View,
StyleSheet,
UIManager,
findNodeHandle,
TouchableOpacity
} from 'react-native';
// import components
import DropDown from './DropDown';
import MyButton from './MyButton';
export default class App extends React.Component {
state = {
show: false,
position: {}
}
// handle showing the dropdown
showDropDown = () => {
if (this.button) {
// use the uimanager to measure the button's position in the window
UIManager.measure(findNodeHandle(this.button), (x, y, width, height, pageX, pageY) => {
const position = { left: pageX, top: pageY, width: width, height: height };
// setState, which updates the props that are passed to the DropDown component
this.setState({show: true, position: { x: pageX + (width / 2), y: pageY + (2 * height / 3) }})
});
}
}
// hide the dropdown
hideDropDown = (item) => {
alert(item)
this.setState({show: false, position: {}})
}
render() {
return (
<View style={styles.container}>
<View style={{height: 100, width: 300, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center'}}>
<MyButton
ref={ref => {this.button = ref}}
onPress={this.showDropDown}
title={'Menu'}
/>
</View>
{/* Anything to be rendered below the DropDown should appear before the DropDown. So for best performance all components should go here. */}
<DropDown show={this.state.show} position={this.state.position} hide={this.hideDropDown}/>
{/* If you place a component here, it will appear above the DropDown and may interfere with how the DropDown works. You should not put anything here. */}
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
}
});
import React from 'react';
import { Text, View, StyleSheet, TouchableWithoutFeedback, TouchableOpacity} from 'react-native';
export default class DropDown extends React.Component {
render() {
if (this.props.show) {
const { y: top, x: left } = this.props.position;
const width = 100;
return (
<TouchableWithoutFeedback onPress={() => this.props.hide('background pressed')}>
<View style={styles.container}>
<View style={[styles.menu, { top, left: left - width/2, width}]}>
<TouchableOpacity style={{width, alignItems: 'center', paddingTop: 5}} onPress={() => this.props.hide('Item 1')}>
<Text>Item 1</Text>
</TouchableOpacity>
<TouchableOpacity style={{width, alignItems: 'center', paddingTop: 5}} onPress={() => this.props.hide('Item 2')}>
<Text>Item 2</Text>
</TouchableOpacity>
<TouchableOpacity style={{width, alignItems: 'center', paddingTop: 5}} onPress={() => this.props.hide('Item 3')}>
<Text>Item 3</Text>
</TouchableOpacity>
<TouchableOpacity style={{width, alignItems: 'center', paddingVertical: 5}} onPress={() => this.props.hide('Item 4')}>
<Text>Item 4</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
);
} else {
return null
}
}
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0
},
menu: {
position: 'absolute',
backgroundColor: 'white',
alignItems: 'center',
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 5,
},
shadowOpacity: 0.36,
shadowRadius: 6.68,
elevation: 11,
}
});
import React from 'react';
import {
Text,
View,
StyleSheet,
TouchableOpacity
} from 'react-native';
export default class App extends React.Component {
render() {
return (
<TouchableOpacity onPress={this.props.onPress}>
<View style={styles.button}>
<Text style={{color: 'white'}}>{this.props.title}</Text>
</View>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
button: {
backgroundColor: '#336699',
padding: 10,
borderRadius: 5
}
});