I am using react-native-dropdown-picker
to offer some options to my user.
Currently, i have two dropdowns in the same screen. The problem is that when i open the first dropdown, the list is getting covered by the second dropdown container.
I already did everything that is listed on the package website that is related to the positioning of the elements (using their zIndex and zIndexInverse properties) but i'm still struggling to get it to work.
Here are some pieces of code:
CustomDropdownComponent:
import { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import DropDownPicker from "react-native-dropdown-picker";
import { LightGray, PlaceholderGray } from '../../../assets/colors';
const styles = StyleSheet.create({
placeholder: {
fontSize: 15,
color: PlaceholderGray
},
interFont: {
fontFamily: "InterRegular"
}
})
const Dropdown = ({ items, returnValue, placeholder, containerStyle, dropdownIndex, dropdownCount }) => {
const [open, setOpen] = useState(false);
const [value, setValue] = useState(false);
const dropdownTheme = require("../../../assets/dropdownTheme");
DropDownPicker.addTheme("DropdownTheme", dropdownTheme);
DropDownPicker.setTheme("DropdownTheme");
function selectValue(value) {
setValue(value);
returnValue(value);
}
console.log((dropdownCount - dropdownIndex) * 1000);
console.log((dropdownIndex + 1) * 1000);
return (
<View style={containerStyle ?? {}}>
<DropDownPicker
zIndex={(dropdownCount - dropdownIndex) * 1000}
zIndexInverse={(dropdownIndex + 1) * 1000}
open={open}
value={value}
items={items}
setOpen={setOpen}
setValue={selectValue}
placeholder={placeholder ?? "Selecione um item"}
placeholderStyle={[styles.placeholder, styles.interFont]}
listItemLabelStyle={styles.interFont}
searchable={true}
/>
</View>
);
}
export default Dropdown;
The screen where i am using the CustomDropdown component:
import { View, Text, StyleSheet } from 'react-native';
import { useState } from 'react';
import PageTitle from '../components/textual/PageTitle';
import Section from '../components/layout/Section';
import Dropdown from '../components/inputs/Dropdown';
import Screen from '../components/layout/Screen';
import { dropdownize } from '../contrib';
import CustomSwitch from '../components/inputs/CustomSwitch';
const EndpointLayout = ({ endpointOptions, setEndpoint, endpointType, switchEndpointType, index, count }) => {
const [open, setOpen] = useState(false);
return (
<View style={styles.endpoint}>
<Dropdown
dropdownIndex={index}
dropdownCount={count}
open={open}
setOpen={setOpen}
containerStyle={styles.endpointDropdown}
items={dropdownize(endpointOptions[endpointType])}
returnValue={setEndpoint}
placeholder={"Selecione um local"}
/>
<View style={styles.endpointType}>
<Text style={styles.endpointTypeText}>{endpointType === "campus" ? "Campus" : "Bairro"}</Text>
<CustomSwitch
switchValue={endpointType === "campus"}
onSwitchHandler={switchEndpointType}
/>
</View>
</View>
);
}
const RegisterRouteScreen = ({ navigation }) => {
const teste = {
"campus": ["Campus1", "Campus2", "Campus3", "Campus4", "Campus5", "Campus6", "Campus7", "Campus8"],
"neighborhood": ["Bairro1", "Bairro2", "Bairro3", "Bairro4", "Bairro5", "Bairro6", "Bairro7", "Bairro8"]
};
const [origin, setOrigin] = useState("");
const [originType, setOriginType] = useState("campus");
const [destiny, setDestiny] = useState("");
const [destinyType, setDestinyType] = useState("campus");
function getEndpointType(currentType) {
return currentType === "campus" ? "neighborhood" : "campus";
}
return (
<Screen>
<PageTitle title={"Cadastrar Rota"} />
<EndpointLayout
index={0}
count={2}
endpointOptions={teste}
setEndpoint={setOrigin}
endpointType={originType}
switchEndpointType={() => { setOriginType(getEndpointType(originType)) }}
/>
<EndpointLayout
index={1}
count={2}
endpointOptions={teste}
setEndpoint={setDestiny}
endpointType={destinyType}
switchEndpointType={() => { setDestinyType(getEndpointType(destinyType)) }}
/>
</Screen>
);
}
const styles = StyleSheet.create({
endpoint: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
},
endpointTypeSwitch: {
marginLeft: 10
},
endpointDropdown: {
width: "60%"
},
endpointType: {
flexDirection: "row",
alignItems: "center",
alignSelf: "center"
},
endpointTypeText: {
fontFamily: "InterRegular",
marginRight: 5
}
})
export default RegisterRouteScreen;
My Dropdown Custom theme (i copied from the light theme and just changed some colors and removed some borders):
import {
Platform,
StyleSheet
} from 'react-native';
import { LightGray, Black, White } from './colors';
export const ICONS = {
ARROW_DOWN: require("../node_modules/react-native-dropdown-picker/src/themes/light/icons/arrow-down.png"),
ARROW_UP: require('../node_modules/react-native-dropdown-picker/src/themes/light/icons/arrow-up.png'),
TICK: require('../node_modules/react-native-dropdown-picker/src/themes/light/icons/tick.png'),
CLOSE: require('../node_modules/react-native-dropdown-picker/src/themes/light/icons/close.png')
};
export default StyleSheet.create({
container: {
width: '100%',
},
style: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
minHeight: 50,
borderRadius: 8,
paddingHorizontal: 10,
paddingVertical: 3,
backgroundColor: LightGray
},
label: {
flex: 1,
color: Black
},
labelContainer: {
flex: 1,
flexDirection: 'row',
},
arrowIcon: {
width: 20,
height: 20
},
tickIcon: {
width: 20,
height: 20
},
closeIcon: {
width: 30,
height: 30
},
badgeStyle: {
flexDirection: 'row',
alignItems: 'center',
borderRadius: 10,
backgroundColor: LightGray,
paddingHorizontal: 10,
paddingVertical: 5
},
badgeDotStyle: {
width: 10,
height: 10,
borderRadius: 10 / 2,
marginRight: 8,
backgroundColor: LightGray
},
badgeSeparator: {
width: 5,
},
listBody: {
height: '100%',
},
listBodyContainer: {
flexGrow: 1,
alignItems: 'center',
},
dropDownContainer: {
position: 'absolute',
backgroundColor: LightGray,
borderRadius: 8,
width: '100%',
overflow: 'hidden',
backgroundColor: "red",
zIndex: 1000
},
modalContentContainer: {
flexGrow: 1,
},
listItemContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 10,
height: 40
},
listItemLabel: {
flex: 1,
color: Black
},
iconContainer: {
marginRight: 10
},
arrowIconContainer: {
marginLeft: 10
},
tickIconContainer: {
marginLeft: 10
},
closeIconContainer: {
marginLeft: 10
},
listParentLabel: {
},
listChildLabel: {
},
listParentContainer: {
},
listChildContainer: {
paddingLeft: 40,
},
searchContainer: {
flexDirection: 'row',
alignItems: 'center',
padding: 10,
borderColor: Black,
},
searchTextInput: {
flexGrow: 1,
flexShrink: 1,
margin: 0,
paddingHorizontal: 10,
paddingVertical: 5,
borderRadius: 8,
color: Black
},
itemSeparator: {
height: 1,
backgroundColor: Black,
},
flatListContentContainer: {
flexGrow: 1
},
customItemContainer: {
},
customItemLabel: {
fontStyle: 'italic',
fontFamily: "InterRegular"
},
listMessageContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 10,
},
listMessageText: {
},
selectedItemContainer: {
},
selectedItemLabel: {
},
modalTitle: {
fontFamily: "InterBold",
fontSize: 18,
color: Black
},
extendableBadgeContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
flex: 1
},
extendableBadgeItemContainer: {
marginVertical: 3,
marginEnd: 7
}
});