react-native-dropdown-picker, how to fix the dropdown picker overlay on other component

10.4k Views Asked by At

I have used react-native-dropdown-picker to show multiple dropdown based on Button click. The dropdown showing as overlay on another component and i can't able to pick items. Anyone can help to fix the problem?

enter image description here

Example code:

import * as React from 'react';
import {View, Text, ScrollView, StyleSheet} from 'react-native';
import DropDownPicker from 'react-native-dropdown-picker';
import {Button, Card} from 'react-native-paper';
//import Constants from 'expo-constants';

// You can import from local files
//import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
//import { Card } from 'react-native-paper';

export default function App() {
  const [myArray, setMyArray] = React.useState([]);
  const [open, setOpen] = React.useState(false);
  const [value, setValue] = React.useState(null);
  const [items, setItems] = React.useState([
    {label: 'Apple', value: 'apple'},
    {label: 'Banana', value: 'banana'},
    {label: 'Orange', value: 'orange'},
    {label: 'Lemon', value: 'lemon'},
  ]);

  const test = () => {
    console.log('Function called');
    setMyArray([{name: 'hello'}]);
  };

  return (
    <View style={styles.container}>
      <Button mode="contained">
        Button 1
      </Button>
      <Text>Hello world</Text>

      <Button mode="contained" >
        Button 2
      </Button>

      <Text>Hello world</Text>

      <Button mode="contained" >
        Button 3
      </Button>
      <Text>Hello world</Text>

      <Button mode="contained" onPress={() => test()} >
        ADD DropDown
      </Button>
      

      {myArray.map((item, index) => {
        
        return (
          <Card key={index} style={{height: 40}}>
            <DropDownPicker
              dropDownDirection="TOP"
              open={open}
              value={value}
              items={items}
              setOpen={setOpen}
              setValue={setValue}
              setItems={setItems}
              zIndex={3000}
              zIndexInverse={1000}
              containerStyle={{position: 'relative', width: '70%', left: '15%', paddingTop: 10}}
              childrenContainerStyle={{
                height: 1030,
              }}
              style={{
                backgroundColor: '#fafafa',
                zIndex: 10,
                position: 'relative',
              }}
              itemStyle={{justifyContent: 'flex-start'}}
              dropDownStyle={{backgroundColor: '#fafafa', height: 100}}
              dropDownContainerStyle={{
                backgroundColor: 'white',
                zIndex: 1000,
                elevation: 5000,
              }}
            />
          </Card>
        );
      })}

      <Button mode="contained">
        Button 4
      </Button>
      <Text>Hello world</Text>

      <Button mode="contained" >
        Button 5
      </Button>

      <Text>Hello world</Text>

      <Button mode="contained" >
        Button 6
      </Button>
      <Text>Hello world</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    textAlign: 'center',
  },
});

Expected: Want to show dropdown without overlay and items should be selectable.

4

There are 4 best solutions below

0
On

You can set the other zIndex of the buttons to 0.

0
On

Don't put backgroundcolor in the dropdownContainerStyle. As far as I understand, the DropdownPicker component does not play well with borderWidth and backgroundColor.

0
On

I've spent a lot of time dealing with this problem and haven't found universal solution for android and ios. It seems that various style changes (like backgroundColor, borderWidth, even parent's view flex direction) of the parent or the dropdown might affect dropdown's functioning. I'd recommend you to to simplify the styles of parent and dropdown as much as possible. Here is what worked for me after cleaning up my styles.

For android:

  • do not use zOrder for the parent component

For ios:

  • set the zOrder of the parent

In your case I would go with something like this:

export default function App() {
     ....
     return (<Card key={index} style={Platform.OS === 'ios' ? {height: 40, zIndex: 10}: {height: 40}}>
           <DropDownPicker
               dropDownDirection="TOP"
               open={open}
               value={value}
               items={items}
               setOpen={setOpen}
               setValue={setValue}
               setItems={setItems}
               containerStyle={{width: '70%', left: '15%', paddingTop: 10}}
               childrenContainerStyle={{
                   height: 1030,
               }}
               itemStyle={{justifyContent: 'flex-start'}}
               dropDownStyle={{backgroundColor: '#fafafa', height: 100}}
          />    
      <\Card>)
}

P.S. not sure what does the Card component add on top of a basic View, so eventually u might go for a simple View if u still have problems with it

0
On

I was able to solve this problem using a conditional zIndex:

<DropDownPicker
  open={open}
  setOpen={setOpen}
  value={value}
  setValue={setValue}
  items={items}
  setItems={setItems}
  placeholder='Selecciona'
  containerStyle={{
    zIndex: open ? 1000 : 0
  }}
/>

It looks like zIndex is not like CSS z-index. In react native the zIndex of children respects the zIndex of the parent. Therefore you must increase the zIndex of the opened dropdown to work.