How to disable header in createDrawerNavigation from Reac Navigation in React Native - javascript

Background
While building a React Native application and using a DrawerNavigator from React Navigation I ended up needing to customize the header that comes with a createDrawerNavigator. I found that I can customize a createStackNavigator though.
createStackNavigator
Can hide the header
Can customize the header.
createDrawerNavigator
Can NOT hide the header
Can NOT customize the header.
Question
How do I hide or customize the header that automatically is added to my app when using the createDrawerNavigator from React Navigation?
Example
createStackNavigator
I can hide the header that appears when using createStackNavigator like this,
const Secure = createStackNavigator(
{
Drawer: {
screen: drawer,
},
},
{
initialRouteName: 'Drawer',
headerMode: 'none',
},
);
createDrawerNavigator
When using createDrawerNavigator nothing I try works to hide or customize the header. I have also searched the documentation and can not find anything referencing how to deal with the header in React Native navigation Version 3 for createDrawerNavigator.

This code will be help the header none for custom drawer component.
const customDrawerContentComponent = (props) => {
Contact: {
screen: ContactScreen ,
navigationOptions: () => ({
header: null
})
}
}
const AppDrawerNavigator = createDrawerNavigator({
Home: {
screen: HomeScreen,
navigationOptions: () => ({
header: null
})
}
}, {
contentComponent: customDrawerContentComponent,
})

Like the answer from Kazi said, you can pass headerMode: null to hide the header from the drawerNavigators and the stacknavigator. The problem with this is that you end up with no headers at all.
So if you want headers for specific screens, there's a header component on react-native-elements that you can add to each screen you want a header on.
Here's an example:
<React.Fragment>
<Header
statusBarProps={{ barStyle: 'light-content' }}
barStyle="light-content"
leftComponent={
<SimpleIcon
name="menu"
color="#34495e"
size={20}
/>
}
centerComponent={{ text: 'HOME', style: { color: '#34495e' } }}
containerStyle={{
backgroundColor: 'white',
justifyContent: 'space-around',
}}
/>
</React.Fragment>
In this example, I had to wrap it on React.Fragment tags because I put this part of the code in the beginning of the render method. I also added a title to the screen and the hamburguer button to open the drawer.
So, basically what I did is, hide the header on both stackNavigators and drawerNavigators then add the component to each of your screens that you do want a header on.

Related

How to use createMaterialTopTabNavigator as a component

Hey I have a search screen "search for songs/artists" So after sending the request i want to appear a "Top Tabs", So I add a Top tab "createMaterialTopTabNavigator" inside separate files and then import it as a component to use it inside Search Screen like this <SearchTabs /> But i got an error
Invariant Violation: The navigation prop is missing for this
navigator. In react-navigation v3 and v4 you must set up your app
container directly. More info:
https://reactnavigation.org/docs/en/app-containers.html
lib
"react-navigation": "^4.1.0",
"react-navigation-drawer": "^2.3.3",
"react-navigation-stack": "^2.0.16",
"react-navigation-tabs": "^2.7.0",
Top Tabs Code
import {createMaterialTopTabNavigator} from 'react-navigation-tabs';
import resultArtists from './resultArtists';
import resultSongs from './resultSongs';
const SearchTabNavigator = createMaterialTopTabNavigator(
{
Songs: {
screen: resultSongs,
navigationOptions: {
tabBarLabel: 'Songs',
},
},
Artists: {
screen: resultArtists,
navigationOptions: {
tabBarLabel: 'Artists',
},
},
},
);
export default SearchTabNavigator;
then i import it in createStackNavigator 'Root.js Navigation file' like this
SearchTabs: {
screen: SearchTabNavigator,
},
here's Search Code "That contains input then i want to appear the top tabs"
class Search extends PureComponent {
render() {
return (
<Container style={styles.container}>
<View style={styles.searchHeader}>
<Input
onChangeText={text => this.search(text)}
value={this.state.searchText}
onSubmitEditing={this.onSearch}
returnKeyType="search"
placeholderTextColor="white"
style={styles.searchInput}
/>
</View>
<SearchTabNavigator />
</Container>
)
}
}
export default Search;
The final result should be something like this
What I tried
I add new createAppContainer to wrap the Top tabs like this in 'Top Tabs file'
export const Tabs = createAppContainer(SearchTabNavigator);
And it's working fine.
but i think it's the wrong way, to add two AppContainer in the same app :\
And when i want to navigate from any item "songs" to Player screen 'it's in Different AppContainer' it's not working!.

Why is it impossible to style a success button in #material-ui

I am using https://material-ui.com/
My objective is to get a success Button, and Chip. Does anyone know how to do this without these hacky solutions: Material-ui #next customize button colors?
The goal isn't to create a styled component, the goal is to be able to use <Button color="success" /> or <Chip color="success" />.
I have tried <Box bgcolor="success.main">{ props => <Chip {...props} />}</Box> to no avail. I would be OK with using Box but not even that works.
It seems a bit ridiculous that these basic UI things are so cumbersome with this library. Success and Error colors should be a default, and they seem to be missing from every single component in this library. Am I missing something?
This is not a full/working example, but hopefully it provides some context. The Main component is included (eventually) via an AuthenticatedRoute within the Router shown in App.js. It doesn't really add anything to show all that complexity, but I wanted to give you some context.
Steps:
Create theme using createMuiTheme.
Add a ThemeProvider component with a theme prop that accepts your theme. This should be a parent to any Component that will make use of the theme, ours is in App.js.
Use the optional argument that makeStyles has to pass your theme into your Component (Main in my example). You can see examples where we access theme properties such as theme.palette.brand.primary.
Use the useStyles hook to create a variable in your component.
Apply those styles to your Component's elements via the className prop. For example, <div className={classes.root}>...</div>
Repeat 3-5 on any Component that needs styling.
I'm still learning my way around Material UI; we just recently migrated from react bootstrap to MUI. We still have some *.scss files laying around, but everything can co-exist. Our eventual plan is to move everything into the makeStyles hooks, but we haven't had time to refactor everything yet.
As a non-CSS guru, I much prefer to write the styling as code (even if I have to write some boilerplate) than to deal with .scss files and specificity/inheritance.
Theme.js:
import { createMuiTheme } from '#material-ui/core/styles';
export default createMuiTheme({
palette: {
brand: {
primary: '#1b3c6b',
primaryLight: '#adceff',
secondary: '#2a5da6',
tertiary: '#bf1e2e',
tertiaryLight: '#c35f69',
},
},
typography: {
color: '#333',
},
sidebar: {
header: {
background: '#2a5da6',
},
content: { background: '#fff' },
},
status: {
danger: 'orange',
},
});
Main.js (partial):
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
},
appBar: {
background: theme.palette.brand.primary,
boxShadow: 'none',
'& .MuiTabs-indicator': {
backgroundColor: theme.palette.brand.primaryLight,
height: 3,
},
position: 'fixed',
zIndex: 1000,
},
}));
const Main = React.memo(props => {
const classes = useStyles();
...
return (
<div className={classes.root}>
<AppBar className={classes.appBar} position="static">
....
</AppBar>
</div>
);
}
App.js (partial):
import { CssBaseline, ThemeProvider } from '#material-ui/core';
import theme from 'Theme/Theme'; // Theme.js from above
...
class App extends Component {
...
render() {
...
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Router>
...
</Router>
</ThemeProvider>
);
}
...
}

How to change height of react-navigation header

On attempt to stylize the header still can't change the height that is on the header
Even using
static navigationOptions = ({navigation}) => ({
title: 'Title',
headerStyle: {height: 60}
})
I prefer to remove entirely the header, and then I used a header from react-native-elements:
createStackNavigator(screens, { headerMode: 'none' })
And then, the Header
import { Header } from 'react-native-elements';
<Header...>
That component consider the top status bar size, and do all things automatically, and run on Expo and ejected apps

How not to unmount previously opened screen of Drawer Navigator

I am using react-native-navigation and trying to create a DrawerNavigator which does not unmount the previously opened screens just like how TabNavigator works. Because one of my screens contains a webview and I do not want it to reload everytime I change screens.
Here is some sample code in App.js..
const Drawer = DrawerNavigator(
{
Home: { screen: Home },
PageWithWebview: { screen: PageWithWebview},
Settings: { screen: Settings },
},
{
initialRouteName: "Home",
contentComponent: props => <SideBar user={global.user} />
}
);
const AppNavigator = StackNavigator(
{
Drawer: { screen: Drawer },
},
{
initialRouteName: "Drawer",
headerMode: "none"
}
);
export default () =>
<Root>
<AppNavigator/>
</Root>;
And in my Sidebar component I have buttons to navigate to a different route depending on what is selected .
onPress={() => this.props.navigation.navigate(selected, { userDetails: global.user })}
In the later versions of react native navigation they added the unmountInactiveScreens property for the DrawerNavigator
unmountInactiveScreens
Whether a screen should be unmounted when navigating away from it. Unmounting a screen resets any local state in the screen as well as state of nested navigators in the screen. Defaults to false.

TabNavigator pass different param from each screen to StackNavigator header

I have Question. How can I pass specific param from each screen to the StackNavigator header in order to come out different kind of components when reached the screen.
I have done some research about this kind of question, but there are not much info that can help me. So I posted here to find some help, hope there are someone who can guide me. Thanks a lot.
const mainNav = TabNavigator({
Home: {
screen: HomeScreen,
param:{
tabval:1
}
},
Live: {
screen: LiveScreen,
param:{
tabval:2
}
},
Radio: {
screen: RadioScreen,
param:{
tabval:3
}
},
} );
function DifferentComponents(tabval){
if(tabval == 1){
//do something
}else if(tabval == 2){
//do something
}else{
//do something
}
}
export const mainStack = StackNavigator({
Home: {
screen: mainNav,
navigationOptions: {
header: (
<View style={styles.topnavscrollview}>
<View style={{width:300}}>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
{this.DifferentComponents(tabval)} <-- Change this when switch to Live tab or others
</ScrollView>
</View>
</View>
),
},
},
Content: { screen: ContentScreen },
});
You can pass in the custom header value as a prop to the component.
Then put something like this at the top the component that you want to customize the header for:
class Home extends React.Component {
// dynamically set header title when component mounts
static navigationOptions = (props) => {
const title = props.myTitleForThisComponent;
return { title }
}
render(){
// render stuff..
}
}
When you navigate to the component via a StackNavigator link, any props that you pass into the component will be available as this.props.navigation.state.params.
For example, if you navigate to your component via StackNavigator like this:
this.props.navigation.navigate(
'Home',
/* below passes into the "Home" component as: this.props.navigation.state.params.title */
{ myCustomTitle: "hello there" }
)}
Then you can create a custom title for the Home page component like this:
static navigationOptions = ({ navigation }) => {
const { myCustomTitle } = navigation.state.params;
return { title: `${myCustomTitle} !!`}
}
hello there !!
Note: when you define your StackNavigator, you do not need to include the option navigationOptions.title, since you are add it dynamically when the component mounts.
However, you can provide generic navigationOptions values within the StackNavigator definition, to provide a "default" values for components that do not add/re-write them dynamically.

Categories

Resources