I'm working on a React native project, in which I use #react-navigation/bottom-tabs: v 6.3.1, for navigation control.
// Navigations.js
<Tab.Screen
name='ExerciseTabScreen'
component={ExerciseStack}
options={( {route, navigation} ) =>({
title : 'Entrenamientos',
headerStyle: {backgroundColor: '#efb810', borderBottomLeftRadius: 6, borderBottomRightRadius: 6},
headerTitleStyle: {color: 'whitesmoke'},
headerShown: 'ExerciseTabScreen' === route.name ? console.log(true) : console.log(false),
headerRight: () => (
<TouchableOpacity onPress={ () => navigation.navigate('<')}>
<Text>Home</Text>
</TouchableOpacity>
),
})}
/>
I can't access the name of the ExerciseTabScreen I swear I've spent a lot of research on it, I even tried to use a Switch and the only thing I get from the console is a True when I change to any of the routes. I already tried wrapping the route.name in square brackets:
headerShown: 'ExerciseTabScreen' === [route.name] ? console.log(true) :
console.log(false),
However I get false when changing to any of the routes. How can I dynamically access the headerShown?
Related
I am trying to find some examples how to implement hidden search bar on top of Screen (react-native) like in Telegram:
And can't find any useful examles. I am using #react-navigation/bottom-tabs. This is one tab of my applicacion:
This is my part of screen that renders bottom tab an search button:
<BottomTab.Screen
name='Products'
component={ProductsScreen}
options={({navigation}: RootTabScreenProps<'Products'>) => ({
title: __('Products'),
tabBarIcon: ({ color }) => <TabBarIcon icon={faShop} color={color} />,
headerRight: () => (
<View style={styles.headerButtons}>
<Pressable
onPress={() => navigation.navigate('Modal')}
style={({ pressed }) => ({
opacity: pressed ? 0.5 : 1,
})}>
<FontAwesomeIcon
icon={faSearch}
size={25}
/*color={Colors[colorScheme].text}*/
style={{ marginRight: 15 }}
/>
</Pressable>
</View>
),
})}
/>
and with all examples that I found - I can't figure out how to do it. Obviously I want that searchbar like this works both on Android and iOs. Please any help. Thanks
Tried different things none of them working, documentation also doesn't help
<MainFlowStack.Navigator
screenOptions={{headerTitleAlign: 'left', shadowColor: 'transparent', headerStyle: {height: 200}}}
>
<MainFlowStack.Screen name="RoutinesList" component={RoutinesListScreen} option={{headerStyle: {height: 600}}} options={{
headerTitle: (props) =>
(<View style={{width: '100%'}}>
<Text style={styles.header1}>
Your Workouts
</Text>
</View>),
headerShadowVisible: false,
headerStyle: {height: 100}
}} />
<MainFlowStack.Screen name="RoutineScreen" component={RoutineScreen} options={({ route }) => ({ title: route.params.name })} />
</MainFlowStack.Navigator>
The headerStyle prop for the Stack.Navigator does not support setting a custom height. From the official documentation:
headerStyle
Style object for header. Supported properties:
backgroundColor
As far as I am concerned, this has changed compared to react-navigation v5.
However, we could provide a custom header component and set a specific height this way.
<Stack.Screen
options={
header: (props) =>
(
<View style={{ height: 100 }}>
...
</View>
),
}
/>
I don't have enough reputation to write a comment, but #fabriziocucci i actually right. You can edit height of header.
I created custom component for header and just passed it in header prop like this:
<Tab.Navigator
screenOptions={({route}) => ({
header: NavHeader,
})}>
<Tab.Screen name="myComponent" component={myComponent}/>
</Tab.Navigator>
and then in styles:
style={{width: '100%', maxHeight: 20}}
David's answer is not entirely correct. Even though the V6 doc doesn't mention it, I just tested that you can actually set the header height as follows:
<Stack.Screen
component={MyScreen}
name="TripScreen"
options={() => ({
headerStyle: { height: 96 }
})}
/>
I have a Viewinside a SafeAreaView in a screen which has postion:absolute. When I include the view, a TouchableOpacity rendered in the header no longer responds in ANDROID (but always works fine in iOS).
Home screen:
render() {
return (
<SafeAreaView style={styles.SafeAreaContainer}>
<View style={styles.homeBackgroundContainer}> {/* <--- offending view! */}
<BlueCircle style={styles.homeBackgroundSvg} />
</View>
<View style={styles.homeView}>
<View style={styles.homeGreetingContainer}>
<Title style={styles.homeGreeting}>Hi, </Title>
<Title style={styles.homeGreetingName}>{username}</Title>
</View>
// Other components
</View>
</SafeAreaView>
);
}
styles.homeBackgroundContainer:
homeBackgroundContainer: {
borderColor: COLOR.transparent,
position: 'absolute',
top: '-50%',
left: '-25%',
right: 0,
bottom: 0,
},
The header is declared in the drawer navigator screen options. Note the TouchableOpacity in the header - this is used to open the drawer.
works in iOS
works from the "Content" screen
works when the homeBackgroundContainer(and its children) are commented out (Home Screen)
DOES NOT WORK IN ANDROID when homeBackgroundContainer is rendered (Home Screen).
Drawer Navigation & Header:
function DrawerContainer() {
return (
<Drawer.Navigator
screenOptions={({navigation}) => ({
headerLeft: titleLogo,
headerStyle: {
// colors only
},
headerTitle: () => {},
headerRight: () => (
<TouchableOpacity
style={styles.hamburgerIconButton}
onPress={() => navigation.toggleDrawer()}>
<Image source={require('../assets/hamburger.png')} />
</TouchableOpacity>
),
})}>
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: true,
// more options
}}
/>
<Drawer.Screen
name="Content"
component={ContentScreen}
options={{
headerShown: true,
}}
/>
</Drawer.Navigator>
);
}
styles.hamburgerIconButton:
hamburgerIconButton: {
marginRight: 20,
},
Other questions on SO have shown that absolute positioning can affect TouchableOpacity. I have tried setting the zIndex of the TouchableOpacity to 1, and also tried setting a positive elevation value but there is no change in behaviour.
Visually, I can see the header colors and content is rendered on top of the view which is the desired state. So if the header is rendered over the view, why isn't the TouchableOpacity responding?
To get the TouchableOpacityin a navigation header to respond on android when there's a view on the screen which has postion: absolute, I had to bring the headerStyle(not the touchable opacity style) forward on the z-axis.
screenOptions={() => ({
headerStyle: {
zIndex: 1,
},
})};
I have a application in React Native, and I'm applying some rotation effects to my drawer, in my application running on the phone, everything works perfectly, but when I migrate to react-native-web it doesn't work correctly, as you can see in the image below, the difference which stays on the screens when it runs on a cell phone and when it runs on the web.
In the web, when the drawer is closed, it still applies the rotation effect, that's doesn't could happen. I put my project into codesandbox.io
To correct this problem, I tried to use Animated.concat(), but it still didn't work:
<Animated.View
style={[
styles.animatedView,
{
borderRadius: "50px",
transform: [
{ rotate: Animated.concat("-8deg") },
{ translateX: Animated.concat("70px") },
{ translateY: Animated.concat("20px") }
]
}
]}
>
<Stack.Navigator
screenOptions={{
headerTransparent: true,
headerTitle: null,
headerTitleAlign: "left",
headerLeft: () => (
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<View style={styles.screenOptionsView}>
<Image
source={require("../assets/images/menu.png")}
style={styles.screenOptionsImage}
/>
<Text style={styles.screenOptionsText}>START</Text>
</View>
</TouchableOpacity>
)
}}
>
<Stack.Screen name="Start" component={Start} />
<Stack.Screen name="Cart" component={Cart} />
<Stack.Screen name="Favorites" component={Favorites} />
<Stack.Screen name="Orders" component={Orders} />
</Stack.Navigator>
</Animated.View>
Do you know how I can make it work on the web as well as it works on mobile?
Thank you very much in advance!!!!
I am new to react native and its navigation modules. I have a simple dashboard.js file where I am using tab navigator like this -
<Tabs.Navigator tabBarOptions={{ activeTintColor: '#ff5757' }}>
<Tabs.Screen
options={{
tabBarIcon: ({ color }) =>
<Icon name='star-border' size={30} padding={15} color={color} />,}}
name={'Orders'}
component={Order}
initialParams={{user}}
/>
<Tabs.Screen
component= {AnotherComponent}
/>
As you can see I am passing InitialParams where I have user props. And I can easily get it in Order component by route.params.
However, in my dashboard component I also have a method that runs every 1 minute and updates user props.
I can't get the updated value of user props in Order component. I am stuck with this for 2 days. In the past I have done like this -
<Tabs.Screen
component = {() => <SomeComponent props= {props}/>}
And it worked fine. But with react-navigation 5 its not working any more.
Please help me if anyone knows. plz.
Thanks a lot.
The initial props seems to be a constant also as per the documentation you have to use redux or context api to update the badge counts in the tabs so I think it will be better to take that approach to handle this problem. Came up with a count changing scenario just like yours using context API.
const CountContext = React.createContext(0);
function HomeScreen() {
return (
<View>
<CountContext.Consumer>
{value => <Text>Home! {value}</Text>}
</CountContext.Consumer>
</View>
);
}
const MyTabs = () => {
const [count, setCount] = React.useState(0);
return (
<CountContext.Provider value={count}>
<View style={{ flex: 1 }}>
<Text>{count}</Text>
<Button title="count" onPress={() => setCount(count + 1)} />
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} options={{ title: 'My home' }} />
<Tab.Screen name="Settings" component={SettingsScreen} options={{ title: 'My home 2' }} />
</Tab.Navigator>
</View>
</CountContext.Provider>
);
};
This way you can skip the navigation params and directly send data to the tab, and this data can be read from other tabs or somewhere down the tree as well.
You can check the full snack here
https://snack.expo.io/#guruparan/5c2b97