react-nativereact-navigationreact-native-flatlist

How to turn a flatlist into a custom navigation bar in react native?


i wish to make a custom navigation bar in react native but the pre built navigators ( stack/tabs ) that come with react navigation are not suitable for what i wish to make. i wanted to know if there is anyway to turn a flatlist into a navigation bar.

here is a basic idea of what i want to achieve :

my code :

import { StyleSheet, Text, View, FlatList, Pressable } from 'react-native'
import React , {useState,useRef} from 'react'
const allData = [
    {name:'Explore',id:'1'},
    {name:'Trending',id:'2'},
    {name:'Post',id:'3'},
    {name:'Messages',id:'4'},
    {name:'Marketplace',id:'5'}
]

const spacing = 10;
const _colors = {
    active: '#eb4034',
    inactive: '#000000',
  }



export default function topBar() {
    const reff = useRef<FlatList>(null)
    const [index,setIndex] = useState(0)
    
    const moveLeft = () => {
        if (index === allData.length -1){
        return;
    }
        setIndex(index+1)
    } 
    const moveRight = () => {
        if (index === 0){
            return;
        }
        setIndex(index-1)
    }
    

    React.useEffect(()=>{
        reff.current?.scrollToIndex({
            index,
            animated: true
        })
    },[index])
  
    return (
    <View style ={styles.containerMain}>
      <FlatList
      ref={reff}
      initialScrollIndex={index}
      keyExtractor={(item)=>item.id}
      data={allData}  
      renderItem={({item, index: findex})=>{return(
        <View style={{
            backgroundColor:findex === index ? _colors.active : _colors.inactive,
            borderWidth:2,
            borderColor:"#fff",
            borderRadius:5,
            margin:spacing,
            padding:5

        
        }}><Text style={styles.items}>{item.name}</Text></View>

      )}}
      horizontal
      showsHorizontalScrollIndicator={false}
      scrollEnabled={false}
      
      />
      <View style={styles.containerButton}>
        <Pressable style={styles.buttonstyle} onPress={moveLeft}>
            <Text style={{fontSize: 20,marginLeft:spacing,marginRight:spacing }}>forward</Text>
        </Pressable>
        <Pressable style={styles.buttonstyle} onPress={moveRight}>
            <Text style={{fontSize: 20,marginLeft:spacing,marginRight:spacing }}>Backwards</Text>
        </Pressable>
      </View>
    </View>
  )
}

const styles = StyleSheet.create({
    containerMain:{
        backgroundColor:'#000000'
    },
    containerButton:{
        flexDirection:'row'
        
    },
    items:{
        padding:2,
        fontSize:30,
    },
    buttonstyle:{
        borderWidth: 2,
        borderColor:'#fff',
        backgroundColor: _colors.active,
        margin: spacing,
        borderRadius:10
        
    }
})

Solution

  • import React, { useState } from 'react';
    import { FlatList, Pressable, StyleSheet, Text, View } from 'react-native';
    import { useNavigation } from '@react-navigation/native';
    
    interface NavigationItem {
      id: string;
      title: string;
    }
    
    const navigationData: NavigationItem[] = [
      { id: 'home', title: 'Home' },
      { id: 'profile', title: 'Profile' },
      { id: 'settings', title: 'Settings' },
    ];
    
    const CustomNavBar = () => {
      const navigation = useNavigation();
      const [selectedIndex, setSelectedIndex] = useState(0);
    
      const onPressItem = (id: string) => {
        setSelectedIndex(navigationData.findIndex((item) => item.id === id));
        navigation.navigate(id);
      };
    
      return (
        <View style={styles.container}>
          <FlatList
            data={navigationData}
            horizontal={true}
            showsHorizontalScrollIndicator={false}
            renderItem={({ item, index }: { item: NavigationItem; index: number }) => (
              <Pressable
                key={item.id}
                style={[styles.navItem, index === selectedIndex && styles.navItemActive]}
                onPress={() => onPressItem(item.id)}
              >
                <Text style={styles.navItemText}>{item.title}</Text>
              </Pressable>
            )}
          />
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        backgroundColor: '#f0f0f0',
        flexDirection: 'row',
      },
      navItem: {
        padding: 10,
      },
      navItemActive: {
        backgroundColor: '#e0e0e0',
      },
      navItemText: {
        fontSize: 16,
      },
    });
    
    export default CustomNavBar;
    

    There I try to show how to make this flatlist into a navigation container.