Andre Song
Andre Song

Reputation: 363

is there a 'fixed header' or 'sticky header' for react native?

Is there a way to have fixed and permeant top-titlebar(I think it's called as Header?) for react native?

Almost like a status bar, it's always there. But it needs to be at the top (even before the 'header' from the react-navigation)

My plan was to put a global-search input there, so anywhere in the app you can search(Search content not affected by the screen that's presented at the moment. Pure global search always available.)

Is there a way to do this? I'm currently working with expo and react-navigation.

--- Edit

I add the screenshot of wireframe that shows what I meant. You'll notice that the Search bar stays at the top regardless the screen you are on. It's a global search bar.

-- Edit

I think I need to say this clearly. I'm trying to do this with ReactNavigation. I think I need to play with 'createAppContainer', or any create navigator function like 'createDrawerNavigator' and figure out a way to put in the fixed header with the navigate-able screens.

Example Navigation with Searchbar

Upvotes: 9

Views: 45373

Answers (3)

Hristo Eftimov
Hristo Eftimov

Reputation: 15733

The react native's component FlatList has a property ListHeaderComponent for rendering a header and another one to stick it stickyHeaderIndices. This is exactly what you need.

In the ListHeaderComponent you will render your search field and with stickyHeaderIndices={[0]} will set it as a sticky header:

<FlatList
    data={ this.state.data }
    renderItem={({item}) =>  this.renderItem(item)}
    ListHeaderComponent={this.renderHeader}
    stickyHeaderIndices={[0]}
/>

Check out the working example.

Upvotes: 17

Andre Song
Andre Song

Reputation: 363

I found the way myself. =)

So the key was to introduce the custom navigator.

Custom Navigator can extend my existing Tab Navigator, and the render part can return almost whatever I want PLUS the regular view that my TabNavigator will have.

My app has Drawer and Tab Navigator. So in my case Drawer Navigator has bunch of routes and one of the routes is the Custom Navigator that's extending TabNavigator.

Here is my code:

const MyTab = createBottomTabNavigator({
  FirstTabStack,
  SecondTabStack,
  ThirdTabStack,
  FourthTabStack,
});

class CustomNavigator extends React.Component {
  static router = MyTab.router;
  render() {
    const { navigation } = this.props;

    return (
      {/* This SafeAreaView is from ReactNavigation. 
          forceInset-bottom-never is needed because  the 
          TabNavigator is already Safe-area-ing the bottom. 
          You don't want to do it again.*/}
      <SafeAreaView style={{ flex: 1 }} forceInset={{ bottom: 'never' }}>
        {/* SearchHeader is zIndex: 1(or elevation: 1) for the absolute 
            positioned stuff that appears and cover the 
            screen after focusing on Input. */}
        <SearchHeader/>
        <MyTab navigation={navigation} />
      </SafeAreaView>
    );
  }
}


export default createDrawerNavigator({
  CustomNavigator,
  SettingsScreen,
  LegalScreen,
  FeedbackScreen,
  VersionScreen,
}, {
  drawerType: 'slide',
  drawerWidth: 260,
});

PS. If you want to have some overlaying absolute position-ed View covering where the TabNavigator is rendered, make sure to use zIndex for iOS, and elevation for Android!! In my case, SearchHeader component has:

const styles = StyleSheet.create({
  container: {
    ...Platform.select({
      ios: {
        zIndex: 1,
      },
      android: {
        elevation: 1
      },
    }),
  },
  {...}
})

Upvotes: 1

Jono
Jono

Reputation: 637

You need to create a component with position: 'absolute' style attribute (and a set minHeight - the height you want your search bar). Then you can import this in your root level component, and put a marginTop: ... style attribute on the rest of your app content (page container) equal to the minHeight you set for your header/search bar.

This way the header will display on all pages, and the rest of your app's content won't display behind the header.

You can find a basic example of this here

Upvotes: 1

Related Questions