Reputation: 363
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.
Upvotes: 9
Views: 45373
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
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
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