I have a requirement of showing a app header with hamburger icon on left , and dropDown Selection in middle , and icon on the right side and below this , I'm showing a search bar . All these has to be added in the header part. below the searchView basically ,I have a list . How can we create the custom header like that?
samplecode:
const Drawer = createDrawerNavigator();
function MyDrawer({ navigation }) {
return (
<Drawer.Navigator
initialRouteName='HomeScreen'
screenOptions={{
headerTitle: (props) => <HeaderComp {...props} />,
headerStyle: {
backgroundColor: '#051E42', //Set Header color
height: 100,
elevation: 15,
shadowColor: '#000'
},
headerRight: () => (
<TouchableOpacity style={{marginRight:10}}>
<Image style={{ height: 30, width: 30, resizeMode: 'contain' }}
source={require('./assets/cart_img.png')}
// source={{ uri: 'asset:/images/cart_img.png' }}
/>
</TouchableOpacity>
),
headerTintColor: 'white'
}}
>
<Drawer.Screen name="HomeScreen"
component={HomeScreen}
/>
<Drawer.Screen name="Profile" component={ProfileScreen} />
<Drawer.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}
Header Component:
const HeaderComp = () => {
const [searchValue, setValue] = useState('');
return (
<View >
<Text style={style.headerTitle}>Custom Header</Text>
{/* <Text style={{top:20}}>dsfskdfsfdjhsfjhs</Text> */}
</View>
)
}
const style = StyleSheet.create({
headerTitle: {
fontWeight: 'bold',
alignItems: 'center',
color: 'white',
left: 60
}
})
export default HeaderComp;
Related
I have a drawer navigation with permanent drawer type and I want to align the drawer items to bottom of the screen instead of the top.
Like this photo:
The code I used to align the did not work for me:
drawerStyle: {
backgroundColor: '#000',
width: 80,
justifyContent:'flex-end',
alignItems:'flex-end'
},
Code for: https://i.stack.imgur.com/Ulr2r.png
export default function App() {
const renderTabIcon = (sourceIcon) => () => {
return (
<Image
style={{
height: 20,
width: 20,
resizeMode: "contain",
}}
source={sourceIcon}
/>
);
};
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Home"
screenOptions={{
drawerStyle: {
width: 57,
},
drawerContentStyle: {
flexDirection: "column-reverse",
},
drawerLabel: "",
}}
>
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{
drawerIcon: renderTabIcon(require("./home.png")),
}}
/>
<Drawer.Screen
name="Search"
component={SearchScreen}
options={{
drawerIcon: renderTabIcon(require("./search.png")),
}}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}
More information: https://reactnavigation.org/docs/drawer-navigator/#screenoptions
I have the Profile tab with it's children. From ChildA I navigate to ChildB, but when I'm trying to go back to Profile, it won't work. I have tried navigation.goBack(null) and useNavigation() hook but without any luck. This is the code I have so far:
ChildA
const ChildA = ({navigation}) =>{
const onClick = (item) =>{
navigation.navigate("ChildB",{
photo:item.uri
})
}
return (
<View style={styles.container}>
<FlatList
data={images}
numColumns={2}
showsVerticalScrollIndicator={false}
style={styles.list}
contentContainerStyle={{ alignItems: 'center', }}
renderItem={({ item }) => (
<TouchableOpacity onPress={()=>onClick(item)}>
<Image
source={item}
style={styles.listItem}
keyExtractor={(item) => item.key}
/>
</TouchableOpacity>
)}
/>
</View>
)
}
ChildB
const ChildB = ({ navigation, route }) => {
console.log(route.name)
const {photo} = route.params
const DEVICE = Dimensions.get("screen")
return (
<View style={styles.container}>
<BackButton onPress={()=>navigation.goBack()} />
<Image source={{ uri: photo }} style={{ width: DEVICE.width, height: DEVICE.height / 2 }} />
<Text>This is the comments section</Text>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
position: 'absolute'
}
})
App.jsx
function Navigation(): JSX.Element {
return (
<Tab.Navigator
shifting={false}
activeColor="#315399"
// inactiveColor="#3e2465"
barStyle={{ backgroundColor: "white" }}>
<Tab.Screen
name="TabA" />
),
}}
component={TabA}
/>
<Tab.Screen
name="TabB" />;
},
}}
component={TabB}
/>
<Tab.Screen
name="Profile" />
),
}}
component={Profile}
/>
</Tab.Navigator>
);
}
const Tab = createMaterialBottomTabNavigator();
const Stack = createStackNavigator();
function App(): JSX.Element {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
{/* Auth Navigator: Include Login and Signup */}
<Stack.Screen
name="Login"
component={Login}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Register"
component={Register}
options={{headerShown:false}}
/>
<Stack.Screen name="ChildB"
component={ChildB}
options={{headerShown:false}}/>
<Stack.Screen
name="ForgotPassword"
component={ForgotPassword}
options={{headerShown:false}}
/>
<Stack.Screen
name="Navigation"
component={Navigation}
// Hiding header for Navigation Drawer
options={{headerShown:false}}
// options={({ route }) => ({
// headerTitle: getHeaderTitle(route),
// })}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
How can I go back from ChildB to Profile? I'm new to react-native so any advice would be appreciated!
I have managed to make it work by passing the navigation as prop instead of the simple function prop I was using.Since I was using a customised back button, the prop function wasn't triggered from screen to stack, only between screens(e.g from Register back to Login).
BackButton before:
export default function BackButton({goBack}) {
return (
<TouchableOpacity onPress={goBack} style={styles.container}>
<FontAwesomeIcon icon={faArrowLeft}/>
</TouchableOpacity>
)
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 10 + getStatusBarHeight(),
left: 4,
zIndex:1
},
image: {
width: 24,
height: 24,
},
})
and used it in another component by passing the prop navigation to that component and then passing the navigation.goBack to the goBack from BackButton:
const componentA = ({navigation})=>{
return(
<View>
<BackButton goBack={navigation.goBack}
</View>
)}
BackButton working:
export default function BackButton({navigation}) {
return (
<TouchableOpacity onPress={navigation.goBack} style={styles.container}>
<FontAwesomeIcon icon={faArrowLeft}/>
</TouchableOpacity>
)
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 10 + getStatusBarHeight(),
left: 4,
zIndex:1
},
image: {
width: 24,
height: 24,
},
})
and Component:
const componentA = ({navigation})=>{
return(
<View>
<BackButton navigation={navigation}
</View>
)}
return (
<Tab.Navigator
barStyle={{backgroundColor: '#F2F2F2'}}
initialRouteName="Catalog">
<Tab.Screen
name="Settings"
options={{
tabBarLabel: 'Alterações',
title: 'Configurações',
tabBarIcon: ({color}) => (
<MaterialCommunityIcons name="cog" color="#000" size={22} />
),
}}>
{(props) => (
<Settings
{...props}
params={{
cpf: params.cpf ? params.cpf : cpf,
}}
/>
)}
</Tab.Screen>
<Tab.Screen
name="Catalog"
options={{
tabBarVisible: false,
title: 'Ofertas',
}}>
{(props) => (
<Catalog
{...props}
params={{
pracaId: params.pracaId ? params.pracaId : pracaId,
}}
/>
)}
</Tab.Screen>
[...]
</Tab.Navigator>
);
The documentations says to use the titleDisplayMode but where? when? I only find solution for older versions. I need it to v5.
Please, can some one help me?
I have include some part of my code to understend how I'm using the lib
There is a shifting prop that you can put to false in your navigator :
<Tab.Navigator
barStyle={{backgroundColor: '#F2F2F2'}}
initialRouteName="Catalog"
shifting={false}
>
.....
Whether the shifting style is used, the active tab icon shifts up to show the label and the inactive tabs won't have a label.
By default, this is true when you have more than 3 tabs. Pass shifting={false} to explicitly disable this animation, or shifting={true} to always use this animation.
https://reactnavigation.org/docs/5.x/material-bottom-tab-navigator#shifting
I have created this example where the HomeScreen always hide the bottom tab and the SettingsStack always show the bottom tab automatically. The key point is basically these lines of code, one have just a screen and the other one have a StackNavigator:
<Tab.Screen name="HomeScreen" component={HomeScreen} />
<Tab.Screen name="SettingsStack" component={SettingsStack} />
This example is similar to the one in the docs https://reactnavigation.org/docs/hiding-tabbar-in-screens/, but with more components.
The code below is in snack, check if this helps you:
https://snack.expo.io/#ronicesarrc/react-navigation-hiding-showing-bottom-tab-navigator
import React from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs';
function SettingsInternalScreen() {
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'orange',
}}>
<Text>SettingsInternalScreen!</Text>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
}}>
<TouchableOpacity
style={{ backgroundColor: 'orange', padding: 16 }}
onPress={() => navigation.navigate('SettingsInternalScreen')}>
<Text>Go to Screen showing bottom tab</Text>
</TouchableOpacity>
</View>
);
}
const SettingStack = createStackNavigator();
function SettingsStack() {
return (
<SettingStack.Navigator>
<SettingStack.Screen name="SettingsScreen" component={SettingsScreen} />
<SettingStack.Screen
name="SettingsInternalScreen"
component={SettingsInternalScreen}
/>
</SettingStack.Navigator>
);
}
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
style={{ backgroundColor: 'gray', padding: 16 }}
onPress={() => navigation.navigate('HomeInternalScreen')}>
<Text>Go to Screen hidding bottom tab</Text>
</TouchableOpacity>
</View>
);
}
function HomeInternalScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>HomeInternalScreen!</Text>
</View>
);
}
const Tab = createMaterialBottomTabNavigator();
const Tabs: React.FC = () => {
return (
<Tab.Navigator>
<Tab.Screen name="HomeScreen" component={HomeScreen} />
<Tab.Screen name="SettingsStack" component={SettingsStack} />
</Tab.Navigator>
);
};
const MainStack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<MainStack.Navigator headerMode="none">
<MainStack.Screen name={'Tabs'} component={Tabs} />
<MainStack.Screen
name={"HomeInternalScreen"}
component={HomeInternalScreen}
/>
</MainStack.Navigator>
</NavigationContainer>
);
}
Im stuck with navigation in Navigation Drawer
my partner did this part of the code and he added DrawerItem(Which will be seen to every user(Admin/client)
i cant figure out how to navigate with it. i tried navigation.navigate("") and its not working
<DrawerItem
label="הגדרות"
style={{
position: "absolute",
bottom: 0,
right: 0,
left: 0,
marginBottom: 60,
borderTopColor: "#afafaf",
borderTopWidth: 3,
}}
onPress={() => logOut()} //Here i need to navigate to the page "aboutUs"
icon={({ color, size }) => (
<MaterialIcons name="settings" color={color} size={size} />
)}
/>
About us stack screen:
const Stack = createStackNavigator();
const aboutStack = ({ navigation }) => {
return (
<Stack.Navigator
initialRouteName={"Aboutus"}
screenOptions={{
headerLeft: () => (
<SimpleLineIcons
name="menu"
style={{ marginLeft: 20 }}
size={24}
color="black"
onPress={() => navigation.toggleDrawer()}
/>
),
}}
>
<Stack.Screen
name="קצת עלינו"
component={Aboutus}
options={{ headerTitleAlign: "center" }}
/>
</Stack.Navigator>
);
};
export default aboutStack;
You can use the props that are passed to the custom drawer and navigate using the name of the screen like below.
onPress={() => props.navigaton.navigate("קצת עלינו")}
I'm using react navigation 5 to build my app navigation system.
I want to add a link to open Notifications scree:
I created a RenderHeaderRight component to override the right component of all my stacks
navigation :
const RenderHeaderRight = ({navigation}) => {
return (
<View style={{flexDirection: 'row-reverse'}}>
<TouchableHighlight
underlayColor={COLORS.DEFAULT}
style={styles.iConMenuContainer}
onPress={() => navigation.openDrawer()}>
<Image source={menu} style={styles.iConMenu} />
</TouchableHighlight>
<TouchableHighlight
underlayColor={COLORS.DEFAULT}
style={styles.notificationsIconContainer}
onPress={() => navigation.navigate('Notifications')}>
<>
<Image source={notifications} style={styles.notificationsIcon} />
<Image source={notifMark} style={styles.badge} />
</>
</TouchableHighlight>
</View>
);
};
In my HomeStackScreen i'm using the RenderHeaderRight :
const HomeStackScreen = ({navigation}) => (
<HomeStack.Navigator
initialRouteName="Home"
headerMode="screen"
mode="modal"
screenOptions={{
headerStyle: {
backgroundColor: COLORS.WHITE,
elevation: 0, // remove shadow on Android
shadowOpacity: 0, // remove shadow on iOS
borderBottomWidth: 0,
},
headerTintColor: COLORS.GREY,
headerTitleStyle: {
fontFamily: 'Montserrat-SemiBold',
fontWeight: '600',
fontSize: 18,
},
}}>
<HomeStack.Screen
name="Home"
component={Home}
options={{
title: 'Expanded',
headerLeft: () => <RenderHeaderLeft />,
headerRight: () => <RenderHeaderRight navigation={navigation} />,
headerTitleAlign: 'left',
}}
/>
<HomeStack.Screen name="HomeDetails" component={HomeDetails} />
</HomeStack.Navigator>
);
When i click on the Header right button to open the Notifications screen i got an error :
The action 'NAVIGATE' with payload {"name":"Notifications"} was not handled by any navigator.
Where shoud i create the stack navigation of Notifications screen ?
I triend to add the notifications like this :
const HomeStackScreen = ({navigation}) => (
<HomeStack.Navigator
initialRouteName="Home"
headerMode="screen"
mode="modal"
screenOptions={{
headerStyle: {
backgroundColor: COLORS.WHITE,
elevation: 0, // remove shadow on Android
shadowOpacity: 0, // remove shadow on iOS
borderBottomWidth: 0,
},
headerTintColor: COLORS.GREY,
headerTitleStyle: {
fontFamily: 'Montserrat-SemiBold',
fontWeight: '600',
fontSize: 18,
},
}}>
<HomeStack.Screen
name="Home"
component={Home}
options={{
title: 'Expanded',
headerLeft: () => <RenderHeaderLeft />,
headerRight: () => <RenderHeaderRight navigation={navigation} />,
headerTitleAlign: 'left',
}}
/>
<HomeStack.Screen name="HomeDetails" component={HomeDetails} />
<HomeStack.Screen
name="Notifications". // add the screen here
component={Notifications}
options={{headerShown: false}}
/>
</HomeStack.Navigator>
);
Removed the unnecessary styling / images
From my understanding you need to have a root Drawer.Navigator and from inside your Home screen, you need a Stack.Navigator there
This article explains the details of combining react-native-navigators
import React from "react"
import { TouchableHighlight, View, Text } from "react-native"
import { NavigationContainer } from "#react-navigation/native"
import { createDrawerNavigator } from "#react-navigation/drawer"
import { createStackNavigator } from "#react-navigation/stack"
const RenderHeaderRight = ({ navigation }) => {
return (
<View style={{ flexDirection: "row-reverse" }}>
<TouchableHighlight onPress={() => navigation.openDrawer()}>
<View>
<Text>Menu</Text>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={() => navigation.navigate("Notifications")}>
<>
<View>
<Text>Image 1</Text>
</View>
<View>
<Text>Image 2</Text>
</View>
</>
</TouchableHighlight>
</View>
)
}
const Stack = createStackNavigator()
const Drawer = createDrawerNavigator()
const Notifications = () => (
<View>
<Text>Notifications</Text>
</View>
)
const Home = () => (
<View>
<Text>Home</Text>
</View>
)
const NotificationsScreen = () => (
<View>
<Text>Notifications Screen</Text>
</View>
)
const HomeScreen = () => (
<View>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
options={({ navigation }) => ({
title: "Home",
headerRight: () => <RenderHeaderRight navigation={navigation} />,
})}
navigationOptions={({ navigation }) => ({
headerTitleAlign: "left",
})}
/>
<Stack.Screen name="Notifications" component={Notifications} />
</Stack.Navigator>
</View>
)
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
)
}