Search code examples
javascriptcssreactjsreact-nativereact-native-flatlist

React Native FlatList with position absolute behind Components


I have multiple SearchBar component, and when I search something it displays a FlatList, I want the Flatlist to be over the rest of the SearchBars components that are below, so I added position: absolute, but it only works with the first element, from the second element, the list displays behind the SearchBars, I also added zIndex: 100 to the List and to the container but it remains the same. The SearchBars are added with an array map:

export default function Game() {

    const arr = [0,1,2,3]
    const data = Data.players

    const [filteredData, setFilteredData] = React.useState([])
    const [actualPosition, setActualPosition] = React.useState(0)

    function search(text) {
        if(text.length < 3) return setFilteredData([])
        if(text.length >= 3){
            setFilteredData(data.filter(i => i.name.toLowerCase().includes(text.toLowerCase())))
        }
    }

    const getItem = (item) => {
        // Function for click on an item
        setActualPosition(actualPosition + 1)
        setFilteredData([])
    };  

    const ItemView = ({ item }) => {
        return (
            // Flat List Item
            <TouchableOpacity onPress={() => getItem(item)}>
                <View style={{flexDirection: 'row'}}>
                    <Text>{item.name}</Text>
                </View>
            </TouchableOpacity>
        );
    };
  
    return (
        <SafeAreaView style={styles.container} >
            {arr.map(i => {
                return (
                <View style={styles.container2} pointerEvents={actualPosition === i ? 'auto' : 'none'}>
                    <SearchBar
                        style={styles.searchBar}
                        placeholder="Search..."
                        onChangeText={(text) => search(text)}
                        onSearchPress={() => console.log("Search Icon is pressed")}
                        onClearPress={() => search("")}
                    />
                    {actualPosition === i && filteredData.length > 0 &&
                        <View style={styles.flatListContainer}>
                            <FlatList 
                                scrollEnabled={false}
                                style={styles.flatList}
                                data={filteredData}
                                keyExtractor={(item, index) => index.toString()}
                                renderItem={ItemView}
                            />
                        </View>
                        }
                </View>
                )
            })}     
        </SafeAreaView>
    );
} 

And the css is:

import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  container2: {
    flexDirection: 'column',
    width: '100%',
    alignItems: 'center',
  },

  searchBarContainer: {
    marginTop: 5,
    width: '125%'
  },
  searchBar: {
    borderBottomWidth: 0.75,
    marginBottom: 5
  },
  flatListContainer: {
    position: 'relative',
    marginLeft: 30,
    zIndex: 100,
    width: '100%'
  },
  flatList: {
    position:'absolute',
    zIndex: 100,
    borderWidth: 0.75,
    backgroundColor: 'white',
    width: '95%'
  },
});

export { styles };

I want all the lists to be displayed over the rest of the components, and why only works with the first element?

Thank you.


Solution

  • In case someone has the same problem, I solved it, maybe it's not the best solution but it works, I just added the following:

    {arr.map(i => {
        return (
            <View style={[styles.container2, {zIndex: -i}]} pointerEvents={actualPosition === i ? 'auto' : 'none'}>
    

    In the View above the SearchBar, zIndex to negative [index] works fine.