How do I hide a certain tab from the tabnavigator? - react-native

I'm trying to hide the "Summary" tab from the tab bar below, but can't quite figure out how I can do this.
const Tab = createBottomTabNavigator({
Overview: {
screen: Overview
},
Camera: {
screen: Camera
},
Summary: {
screen: Summary
}
}, {
tabBarPosition: 'top',
swipeEnabled: true,
tabBarOptions: {
activeTintColor: '#f2f2f2',
activeBackgroundColor: '#2EC4B6',
inactiveTintColor: '#666',
labelStyle: {
fontSize: 22,
padding: 12
}
}
});
export default createAppContainer(Tab);
How can I do this?

I've solved this by using a custom BottomBar and hiding the tab when the screen appeared:
tabBarComponent: (props) => (<BottomBar {...props} ></BottomBar>) //Navigator Configs
The bottombar i have is like this:
import React from 'react'
import { BottomTabBar } from 'react-navigation-tabs'
import { View, TouchableWithoutFeedback, Dimensions } from 'react-native'
import { StyleSheet } from 'react-native';
var { height } = Dimensions.get("window")
const HiddenView = () => <View style={{ display: 'none' }} />
const TouchableWithoutFeedbackWrapper = ({
onPress,
onLongPress,
testID,
accessibilityLabel,
...props
}) => {
return (
<TouchableWithoutFeedback
onPress={onPress}
onLongPress={onLongPress}
testID={testID}
hitSlop={{
left: 15,
right: 15,
top: 5,
bottom: 5,
}}
accessibilityLabel={accessibilityLabel}
>
<View {...props} />
</TouchableWithoutFeedback>
)
}
export default TabBarComponent = props => {
return <BottomTabBar
{...props}
style={styles.bottomBarStyle}
getButtonComponent={({ route }) => {
if (route.key === "Summary" )
return HiddenView
else return TouchableWithoutFeedbackWrapper
}}
/>
}
const styles = StyleSheet.create({
bottomBarStyle: {
height: (height * 10.625) / 100
}
})
Let me know if this creates new issues

Related

how do I style my react native top tab navigation to have a background color and icons

I am a bit new to react native and I am having a bit of difficulty styling my top tab navigation
how do I style my react native top tab navigation to have a background color and icons
See code to my top tab navigation in react native
I have tried all I know, nothing seems to be working
see how I want it to look
see how it looks
see my code below
import "react-native-gesture-handler"
import React from "react"
import { DefaultTheme } from "#react-navigation/native"
import { AppearanceProvider, useColorScheme } from "react-native-appearance"
import { createMaterialTopTabNavigator } from "#react-navigation/material-top-tabs"
import { PersonalSetupScreen } from "./tabs/personal-setup"
import { CompanySetupScreen } from "./tabs/company-setup"
import { Images } from "../../config"
const Tab = createMaterialTopTabNavigator()
const MyDarkTheme = {
// Ovverride dark theme with your theme
dark: true,
colors: {
primary: "rgb(255, 255, 255)",
background: "rgb(33, 20, 122)",
card: "rgb(255, 255, 255)",
text: "rgb(255, 255, 255)",
border: "rgb(199, 199, 204)",
notification: "rgb(255, 69, 58)",
},
}
export default function HomeTabs() {
const scheme = useColorScheme()
return (
<Tab.Navigator >
<Tab.Screen
name="PersonalSetup"
component={PersonalSetupScreen}
options={({ navigation }) => ({
tabBarLabel: "Personal Details",
activeTintColor: "#21147a",
inactiveTintColor: "21147a",
activeBackgroundColor: "#21147a",
inactiveBackgroundColor: "#21147a",
style: {
backgroundColor: "#21147a",
},
})}
/>
<Tab.Screen
name="CompanySetup"
component={CompanySetupScreen}
options={({ navigation }) => ({
tabBarLabel: "Company Details",
activeTintColor: "#21147a",
inactiveTintColor: "21147a",
activeBackgroundColor: "#21147a",
inactiveBackgroundColor: "#21147a",
style: {
backgroundColor: "#21147a",
},
})}
/>
</Tab.Navigator>
)
}
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
const TopTab = createMaterialTopTabNavigator();
const Tab = () => {
return (
<TopTab.Navigator
screenOptions={{
tabBarActiveTintColor:'white',
tabBarIndicatorStyle: {
backgroundColor: 'white',
height: 2
},
tabBarScrollEnabled: true,
tabBarLabelStyle: {fontSize: 20},
tabBarItemStyle: { width: 150, },
tabBarStyle: {
height: 40,
backgroundColor: '#c21a0c',
},
}}
>
<TopTab.Screen name ='PERSONAL DETAILS' component={Personal} Options={{
tabBarIcon: () => (
<MaterialCommunityIcons name="search-web" size={24} />
)}} />
<TopTab.Screen name ='COMPANY DETAILS' component = {Company} />
<TopTab.Screen name ='CONTACT DETAILS' component = {FOX} />
<TopTab.Screen name ='PROFILE' component = {Google} />
</TopTab.Navigator>
)
}
According to the documentation here: Material Top Tab Navigator
You can pass in a tabBarIcon.
You can also pass your own custom component as a TabBar Button that you can style however you want (Text + Icon + BackgroundColor ...)
you might have already found out the solution.
Here is the complete example from reactnavigation.org.
import { Animated, View, TouchableOpacity } from 'react-native';
function MyTabBar({ state, descriptors, navigation, position }) {
return (
<View style={{ flexDirection: 'row' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
// The `merge: true` option makes sure that the params inside the tab screen are preserved
navigation.navigate({ name: route.name, merge: true });
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
const inputRange = state.routes.map((_, i) => i);
const opacity = position.interpolate({
inputRange,
outputRange: inputRange.map(i => (i === index ? 1 : 0)),
});
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Animated.Text style={{ opacity }}>
{label}
</Animated.Text>
</TouchableOpacity>
);
})}
</View>
);
}
// ...
<Tab.Navigator tabBar={props => <MyTabBar {...props} />}>
{...}
</Tab.Navigator>
Reference: https://reactnavigation.org/docs/material-top-tab-navigator/#tabbar
For more information, please go through this link.

How to re render a screen and it all compoent after moving from one tab to another and back to first tab?

I am trying get re render a screen every time the user presses a tab or moving from one tab to another and then to first tab. I also placed a custom header in the screen. Same header on all the other tabs too getting some state from Asynchronous storage but it is also not refreshing once the screen has loading. I am using react navigation. Is there any method in navigation which will be called whenever tab is focused.
const AppStack = createBottomTabNavigator(
{
Search: SearchScreen,
Saved: SavedScreen,
Explore: ExploreStack,
Offers: OffersScreen,
Profile: ProfileScreen,
},
{
initialRouteName: 'Explore',
navigationOptions: ({navigation})=>({
tabBarIcon: ({focused, tintColor})=>{
const { routeName } = navigation.state;
let iconName, iconSize;
switch(routeName) {
case "Search":
iconName = `ios-search${focused ? '' : '-outline'}`;
break;
case "Saved":
iconName = `ios-heart${focused ? '' : '-outline'}`;
break;
case "Explore":
iconName = `ios-navigate${focused ? '' : '-outline'}`;
break;
case "Offers":
iconName = `ios-pricetag${focused ? '' : '-outline'}`;
break;
case "Profile":
iconName = `ios-person${focused ? '' : '-outline'}`;
break;
default:
break;
}
return <Icon name={iconName} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: 'black',
inactiveTintColor: 'grey',
activeBackgroundColor: '#abaf9b',
labelStyle: {
fontSize: 15,
},
// style for tabbar
style: {
backgroundColor: '#ffffff',
height: 60,
justifyContent: 'space-around',
alignContent: 'center',
alignItems: 'center',
},
// style for tab
tabStyle: {
paddingTop: 7,
paddingBottom: 7
}
},
}
)
This is one of the tab. Other tabs a very similar using same component but the different apis.
import React, { Component } from 'react';
import { View, Image, ActivityIndicator, TouchableWithoutFeedback, TouchableHighlight, AsyncStorage } from 'react-native';
import HeaderComponent from '../components/Header';
import SomeComponent from '../components/Some';
import { Container, Content, Icon, Spinner} from 'native-base';
class FirstScreen extends Component{
constructor(props){
super(props)
this.state = {
somelist: [],
name: '',
userId: '',
isloading: true,
location: ''
};
this.getUser();
}
componentDidMount(){
this.getLocation();
}
getLocation = async() => {
const result = await AsyncStorage.getItem('location');
console.log("Location " +result)
this.setState({location: result});
}
getUser = async() => {
const result = await AsyncStorage.getItem('user');
const data = JSON.parse(result);
console.log("data : "+data)
this.setState({name: data.name, userId: data.userId})
}
componentWillMount(){
console.log("Component will mount")
//For demo
fetch('http://someapi.co/api/listing')
.then(response => response.json())
.then(data => {
this.setState({ somelist: data, isloading: false }, function(){console.log(this.state.somelist, this.state.isloading)})
})
.catch(function(error){
console.log("Error : "+error);
});
//console.log(this.state.barlist);
}
renderComponent(){
if(this.state.isloading == true){
return (
<View style={{ flex: 1, justifyContent: 'center', height: 300 }}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
}
return this.state.somelist.map( user=>
<SomeComponent key={user.id}
onPress={()=>this.props.navigation.navigate('OtherScreen', {'Id': user.id, 'userId': this.state.userId})}
image={user.image[0].imageName}
/>
);
}
render(){
console.log(this.state.userId)
return (
<Container>
<HeaderComponent
profilePress={()=>this.props.navigation.navigate('Profile')}
seachPress={()=>this.props.navigation.navigate('SearchSetting')}
// location={this.state.location}
/>
<TouchableHighlight
style={{position: 'absolute', bottom: 20, zIndex:999999, right: 20 }}
onPress={()=>this.props.navigation.navigate('Map')}
>
<Image source={require('../images/navigation_icon.png')} style={{height: 50, width: 50}}/>
</TouchableHighlight>
<Content>
<View style={{padding: 0, margin: 0}}>
{this.renderComponent()}
</View>
</Content>
</Container>
);
}
}
export { SomeScreen };
You can access the event listeners in react-navigation as mentioned here
// call when the screen is focused
componentDidMount () {
this._onFocusListener = this.props.navigation.addListener('didFocus', (payload) => {
// refresh the component here
// or update based on your requirements
});
}
Please refer the link: https://reactnavigation.org/docs/en/navigation-prop.html#addlistener-subscribe-to-updates-to-navigation-lifecycle
There are 2 different ways I found below,
// call when the screen is focused
componentDidMount () {
this._navListener = this.props.navigation.addListener('didFocus', (payload) => {
// update based on your requirements
});
}
OR
import { NavigationEvents } from "react-navigation";
...
class HomeScreen extends React.Component {
render() {
return (
<View>
<NavigationEvents
onWillFocus={() => {
// update based on your requirements!
}}
/>
<Text>Home</Text>
</View>
);
}
}

Deep Linking in Nested Navigators in react navigation

I am using react-navigation and as per the structure of my application, we have a tab navigator inside stack navigator, I am not been able to find any proper guide for implementing Deep-Linking.
https://v1.reactnavigation.org/docs/deep-linking.html. this doesn't give any reference for nested navigators.
You have to basically pass a path to every upper route untill you come to you nested route. This is indipendent of the type of navigator you use.
const HomeStack = createStackNavigator({
Article: {
screen: ArticleScreen,
path: 'article',
},
});
const SimpleApp = createAppContainer(createBottomTabNavigator({
Home: {
screen: HomeStack,
path: 'home',
},
}));
const prefix = Platform.OS == 'android' ? 'myapp://myapp/' : 'myapp://';
const MainApp = () => <SimpleApp uriPrefix={prefix} />;
In this case to route to an inner Navigator this is the route: myapp://home/article.
This example is using react-navigation#^3.0.0, but is easy to transfer to v1.
So, after the arrival of V3 of react navigation, things got extremely stable. Now i will present you a navigation structure with deep-linking in a Switch navigator -> drawerNavigator-> tabNavigator -> stack-> navigator. Please go step by step and understand the structure and keep referring to official documentation at everystep
With nested navigators people generally mean navigation structure which consists of drawer navigator, tab navigator and stackNavigator. In V3 we have SwitchNavigator too. So let's just get to the code,
//here we will have the basic React and react native imports which depends on what you want to render
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View, Animated, Easing, Image,
Button,
TouchableOpacity, TextInput, SafeAreaView, FlatList, Vibration, ActivityIndicator, PermissionsAndroid, Linking
} from "react-native";
import { createSwitchNavigator, createAppContainer, createDrawerNavigator, createBottomTabNavigator, createStackNavigator } from "react-navigation";
export default class App extends Component<Props> {
constructor() {
super()
this.state = {
isLoading: true
}
}
render() {
return <AppContainer uriPrefix={prefix} />;
}
}
class WelcomeScreen extends Component {
state = {
fadeAnim: new Animated.Value(0.2), // Initial value for opacity: 0
}
componentDidMount() {
Animated.timing( // Animate over time
this.state.fadeAnim, // The animated value to drive
{
toValue: 1,
easing: Easing.back(), // Animate to opacity: 1 (opaque)
duration: 1000,
useNativeDriver: true // Make it take a while
}
).start(); // Starts the animation
}
render() {
let { fadeAnim } = this.state;
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center", backgroundColor: '#000' }}>
<Animated.View // Special animatable View
style={{ opacity: fadeAnim }}
>
<TouchableOpacity
onPress={() => this.props.navigation.navigate("Dashboard")}
style={{
backgroundColor: "orange",
alignItems: "center",
justifyContent: "center",
height: 30,
width: 100,
borderRadius: 10,
borderColor: "#ccc",
borderWidth: 2,
marginBottom: 10
}}
>
<Text>Login</Text>
</TouchableOpacity>
</Animated.View>
<Animated.View // Special animatable View
style={{ opacity: fadeAnim }}
>
<TouchableOpacity
onPress={() => alert("buttonPressed")}
style={{
backgroundColor: "orange",
alignItems: "center",
justifyContent: "center",
height: 30,
width: 100,
borderRadius: 10,
borderColor: "#ccc",
borderWidth: 2
}}
>
<Text> Sign Up</Text>
</TouchableOpacity>
</Animated.View>
</View>
);
}
}
class Feed extends Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Button
onPress={() => this.props.navigation.navigate("DetailsScreen")}
title="Go to details"
/>
</View>
);
}
}
class Profile extends Component {
render() {
return (
<SafeAreaView style={{ flex: 1, }}>
//Somecode
</SafeAreaView>
);
}
}
class Settings extends Component {
render() {
return (
<View style={{ flex: 1 }}>
//Some code
</View>
);
}
}
const feedStack = createStackNavigator({
Feed: {
screen: Feed,
path: 'feed',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Feed",
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="md-menu"
size={30}
onPress={() => navigation.openDrawer()}
/>
)
};
}
},
DetailsScreen: {
screen: Detail,
path: 'details',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details",
};
}
}
});
const profileStack = createStackNavigator({
Profile: {
screen: Profile,
path: 'profile',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Profile",
headerMode: 'Float',
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="md-menu"
size={30}
onPress={() => navigation.openDrawer()}
/>
)
};
}
},
DetailsScreen: {
screen: Detail,
path: 'details',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details"
};
}
}
});
const settingStack = createStackNavigator({
Settings: {
screen: Settings,
path: 'settings',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Settings",
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="md-menu"
size={30}
onPress={() => navigation.openDrawer()}
/>
)
};
}
},
DetailsScreen: {
screen: Detail,
path: 'details',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details"
};
},
}
});
const DashboardTabNavigator = createBottomTabNavigator(
{
feedStack: {
screen: feedStack,
path: 'feedStack',
navigationOptions: ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarLabel: "Feed",
tabBarVisible,
//iconName :`ios-list${focused ? '' : '-outline'}`,
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-list" color={tintColor} size={25} />
)
};
}
},
profileStack: {
screen: profileStack,
path: 'profileStack',
navigationOptions: ({ navigation, focused }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false
}
return {
tabBarVisible,
tabBarLabel: "Profile",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-man" color={tintColor} size={25} />
)
};
// focused:true,
}
},
settingStack: {
screen: settingStack,
path: 'settingsStack',
navigationOptions: ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarVisible,
tabBarLabel: "Settings",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-options" color={tintColor} size={25} />
)
}
}
},
},
{
navigationOptions: ({ navigation }) => {
const { routeName } = navigation.state.routes[navigation.state.index];
return {
// headerTitle: routeName,
header: null
};
},
tabBarOptions: {
//showLabel: true, // hide labels
activeTintColor: "orange", // active icon color
inactiveTintColor: "#586589" // inactive icon color
//activeBackgroundColor:'#32a1fe',
}
}
);
const DashboardStackNavigator = createStackNavigator(
{
DashboardTabNavigator: {
screen: DashboardTabNavigator,
path: 'dashboardtabs'
},
DetailsScreen: {
screen: Detail,
path: 'details',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details"
};
}
}
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="md-menu"
size={30}
onPress={() => navigation.openDrawer()}
/>
)
};
}
}
);
const AppDrawerNavigator = createDrawerNavigator({
Dashboard: {
screen: DashboardStackNavigator,
path: 'welcome'
},
DetailsScreen: {
screen: Detail,
path: 'friends',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details",
};
}
}
});
//Switch navigator , will be first to load
const AppSwitchNavigator = createSwitchNavigator({
Welcome: {
screen: WelcomeScreen,
},
Dashboard: {
screen: AppDrawerNavigator,
path: 'welcome'
}
});
const prefix = 'myapp://';
const AppContainer = createAppContainer(AppSwitchNavigator);
For the process to setup React-navigation deep-linking please follow the official documentation
DetailsScreen was in my different folder and that will have class component of your choice
To launch the App the deep-link URL is myapp://welcome
To go to root page the deep-link URL is myapp://welcome/welcome
(this will reach at first page of first tab of tab navigator)
To go to any particular screen of tab navigator (suppose details
screen in profile tab) -
myapp://welcome/welcome/profileStack/details
const config = {
Tabs: {
screens: {
UserProfile: {
path: 'share//user_share/:userId',
parse: {
userId: (userId) => `${userId}`,
},
},
},
},
};
const linking = {
prefixes: ['recreative://'],
config,
};
if you have a screen in tab navigator you can do it like this via react-navigation v5

How can TabNavigator child screen refer to parent StackNavigator?

The structure of the application is this.
StackNavigator
StackA-Screen(TabNavigator)
TabChildA-Screen
TabChildB-Screen
...
StackB-Screen
code in App.js
const TabComponent = TabNavigator(
{
TabChildA-Screen: {
screen: TabChildA,
},
TabChildB-Screen: {
screen: TabChildB,
}
},
{
tabBarPosition: "bottom",
animationEnabled: false,
swipeEnabled: false
}
);
const StackComponent = StackNavigator(
{
StackA-Screen: {
screen: TabComponent,
navigationOptions: ({ navigation }) => ({
headerBackTitle: null,
headerRight: (
<TouchableWithoutFeedback
onPress={() =>
navigation.navigate("StackB-Screen", { space: "" }) // can't navigate to "StackB-Screen".
}
>
<MaterialIcon
name="playlist-add"
size={Sizes.NavigationBar.Icon.Size}
style={{ padding: 8, color: Colors.White }}
/>
</TouchableWithoutFeedback>
)
})
},
StackB-Screen: {
screen: StackB,
}
},
{
initialRouteName: "StackA-Screen",
mode: "modal"
}
);
export default StackComponent;
I want to navigate TabChildA-Screen to StackB-Screen.
But, TabChildA-Screen can refer to navigator is navigator of TabNavigator.
code in TabChildA-Screen
import React, { Component } from "react";
import { Button, Text, View } from "react-native";
class StackB extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center"
}}
>
<Button
onPress={ () =>
this.props.navigation.navigate("StackB-Screen") // can't navigate to "StackB-Screen".
}
title="move to StackB-Screen"
/>
</View>
);
}
}
export default StackB;
How to TabChildA-Screenrefer StackNavigator ?

Header with gradient image overlay

I am trying to add a header with a gradient image overlay to an app I am making.
The below code has been trimmed down and simplified in the hope to make it meaningful to you.
The header should be visible on all screens, where some screens show the back button and only the front screen show a logo and settings to the right.
How can I solve that?
import { TabNavigator, StackNavigator } from 'react-navigation';
import React, { Component } from 'react';
import Example from '../components/example';
const navContainer = (Comp, options) => {
return StackNavigator({
Main: {
screen: Comp,
navigationOptions: options
},
S1: {
screen: Example
},
S2: {
screen: Example,
navigationOptions: ({ navigation }) => {
return {
headerTitle: <Example {...navigation.state.params} />,
headerStyle: {
backgroundColor: 'white'
}
}
}
},
S3: {
screen: Example,
navigationOptions: ({ navigation }) => {
return {
headerTitle: <Example {...navigation.state.params} />,
headerStyle: {
backgroundColor: 'white'
}
}
}
},
S4: {
screen: Example,
navigationOptions: ({ navigation }) => {
return {
headerTitle: <Example {...navigation.state.params} />,
headerStyle: {
backgroundColor: 'white'
}
}
}
}
},
{
cardStyle: {
backgroundColor: 'green'
}
})
}
const navOptions = title => {
return {
headerTitle: title,
headerBackTitle: null,
headerStyle: {
backgroundColor: 'transparent'
}
}
}
const NavTab = TabNavigator(
{
M1: {
screen: navContainer(Example, navigation => ({
headerTitle: <Example />,
headerRight: <Example { ...navigation } />,
headerStyle: {
backgroundColor: 'transparent'
}
}))
},
M2: {
screen: navContainer(Example, navOptions('M2'))
},
M3: {
screen: navContainer(Example, navOptions('M3'))
},
M4: {
screen: navContainer(Example, navOptions('M4'))
}
},
{
tabBarPosition: 'bottom',
lazy: true,
tabBarOptions: {
inactiveBackgroundColor: 'white',
activeBackgroundColor: 'white'
}
}
);
export default NavTab;
The example component:
import React, { Component } from 'react';
import { StyleSheet, View, Text } from 'react-native';
export default class Example extends Component {
static style = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})
render () {
return (
<View style={ Example.style.container }>
<Text>hello</Text>
</View>
);
}
}
My first attempt was to overwrite Header._renderHeader, but the status bar was still not covered.
The final solution is below the <hr />.
import React from 'react';
import { Header } from 'react-navigation';
import { StyleSheet, View, StatusBar, Image } from 'react-native';
import img_gradient from '../images/headerbg.png';
const style = StyleSheet.create({
header: {
flexDirection: 'row'
},
img: {
width: '100%',
height: '100%',
resizeMode: 'stretch'
}
});
export default class NavHeader extends Header {
_renderHeader (props) {
const left = this._renderLeft(props);
const right = this._renderRight(props);
const title = this._renderTitle(props, {
hasLeftComponent: left !== null,
hasRightComponent: right !== null
});
return (
<View key={ `scene_${ props.scene.key }` } style={ [StyleSheet.absoluteFill, style.header] }>
<StatusBar barStyle="light-content" />
<Image source={ img_gradient } style={ style.img }>
{ title }
{ left }
{ right }
</Image>
</View>
);
}
}
Here's how I solved it, by putting my root element inside BgImg: <BgImg><App /></BgImg>.
import React, { Component } from 'react';
import { StyleSheet, Image, StatusBar } from 'react-native';
import img_gradient from '../images/headerbg.png';
export default class BgImg extends Component {
static style = StyleSheet.create({
img: {
width: '100%',
height: '100%',
resizeMode: 'stretch'
}
})
render () {
return (
<Image source={ img_gradient } style={ BgImg.style.img }>
<StatusBar barStyle="light-content" />
{ this.props.children }
</Image>
);
}
}