skip to Main Content

I made a search input on the top of a map view to look in the data. When the flatlist shows up I have two problems that I don’t understand:

  • I can’t scroll in the list to search into it.
  • And when I do that, it moves the map behind.

The TouchableOpacity of the item in the list works. So it’s like I can touch both views.

printscreen

Here is the code:

import { StyleSheet, Text, TextInput, View, TouchableHighlight, Pressable, TouchableOpacity, FlatList } from 'react-native'
// import { FlatList } from 'react-native-gesture-handler'
import React, { useState} from 'react'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { useGetAllBars } from '../../hooks/queries-hook';
import Loader from '../../components/ui/loader';
const Search = () => {
    const { getbars, isLoading, data, error } = useGetAllBars();
    const [showList, setShowList] = useState(false)
    const [text, setText] = useState("")
    const [list, setList] = useState(null)

    const handleSearch = (text) => {
        if (text) {
            let filteredList = data.filter((item) =>
                item.name.toLowerCase().includes(text.toLowerCase()))
            setList(filteredList)
        }
    }
    const renderItem = ({ item }) => {
        return (
            <TouchableOpacity onPress={() => { }} >
                <View style={styles.item}>
                    <Text style={styles.simpleText}>{item.name}</Text>
                </View>
            </TouchableOpacity>
        );
    };

    return (
        <View style={styles.searchView}>
            {
                text.length > 2 && showList ?
                    <View style={styles.listView}>

                        {
                            isLoading ? <Loader fullScreen={false} /> :
                                <View style={{ height: 320 }}>
                                    <FlatList
                                        data={list.slice(0, 50)}
                                        renderItem={renderItem}
                                        keyExtractor={item => item.id}
                                    />
                                </View>
                        }
                    </View>
                    :
                    text != "" &&
                    <View style={styles.listView}>
                        <Text style={styles.alert}>Minimum 3 caractères</Text>
                    </View>
            }
            <View style={styles.searchInput}>
                <MaterialCommunityIcons name="magnify" size={20} color={'#000'} />
                <TextInput style={styles.textToSearch}
                    placeholder='Search for a place'
                    placeholderTextColor={"#777777"}
                    onFocus={() => {
                        !data && getbars()
                        setShowList(true)
                    }}
                    onChangeText={(text) => {
                        setText(text);
                        handleSearch(text);
                    }}
                    value={text}
                />
                {
                    text != "" &&
                    <TouchableOpacity
                        onPress={() => { setText("") }} >
                        <MaterialCommunityIcons name="close-circle" size={30} color={'#777'} />

                    </TouchableOpacity>
                }
            </View>
        </View>
    )
}

export default Search

const styles = StyleSheet.create({

    searchView: {
        margin: 5,
        width: "95%",
        position: 'absolute',
        zIndex: 10,
        bottom: 0,
    },
    listView: {
        margin: 5,
        marginVertical: 20,
        width: "100%",
        position: 'absolute',
        bottom: 40,
        backgroundColor: "#fff",
        borderRadius: 10,
        minHeight: 30,
        shadowColor: "#000",
        shadowOffset: {
            width: 0,
            height: 2
        },
        shadowOpacity: 0.25,
        shadowRadius: 4,
        elevation: 5
    },
    searchInput: {
        paddingHorizontal: 10,
        lineHeight: 20,
        flexDirection: 'row',
        width: "80%",
        backgroundColor: '#d9dbda',
        borderRadius: 10,
        alignItems: 'center',
        height: 50,
    },
    textToSearch: {
        fontSize: 20,
        color: "#777777",
        width: "85%",
        paddingHorizontal: 5,
        paddingVertical: 0,
    },
    simpleText: {
        color: "#777777"
    },
    alert: {
        color: "#634a",
        lineHeight: 30,
        flexDirection: 'row',
        alignItems: 'center',
        margin: 3
    },
    item: {
        flexDirection: "row",
        justifyContent: 'flex-start',
        margin: 2
    },
})

Could someone explain me what I am missing or what I dont understand ?

2

Answers


  1. I think the problem is that the parent of the absolute positioned list is collapsed and make the list become an overflowed content. React native has a wired behavior that touching interaction on overflowed content is workable but guesture moveing is not. That’s why your gesture moving event will be responded by the map behind as it is the only responder.

    Try import FlatList from react-native-gesture-handler instead of using the react-native one. And you may need to set the responder of your gesture event when the list shows.

    import { FlatList } from 'react-native-gesture-handler'.

    Or just set the parent height when the list shows to ensure the list will not be overflowed

    Login or Signup to reply.
  2. Would need to see the parent structure of how the map is being render alongside search.

    This could be a layering issue on android. Android specifically needs to have elements that appear on top return a line lower than the jsx elements that and rendered below.

    <View>
      <Map />
      <Search />
    </View>
    

    Without this structure you have to use elevation (but that may not work with a OpenGL map layer).

    Noting that opengl layers can behave differently than simple react native views, especially on android.

    If this is not on android, look at zindex for ios. Ios should be more flexible with view hierarchy.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search