React Navigation TabBar Active Tab - react-native

I'm trying to create TabBar using react-navigation createBottomTabNavigator. I want to add this red thing above Tab when it's active. Any ideas how to achieve this? I was thinking about changing Tab container if it's active, but couldn't find how to do this.

If your tabs point to another stack navigators, the best idea would be to pass a custom component to tabBarIcon. Something like that:
SomeStack.navigationOptions = {
tabBarIcon: ({ focused }) => (
<TabBarButton
isFocused={focused} // render red thing above if focused
iconName="icon name"
/>
),
};

Related

How can I render DrawerLayout from react-native-gesture-handler on top of my TabNavigator?

App using react-navigation 6
App have TabNavigator and I need to have Drawer that rendered on top of TabNavigator that render Items, that could be selected, and based on what Item was selected I need to change screen in the same Tab in TabNavigator.
The DrawerNavigator solution doesn't fit my needs. Because when user select another Tab from TabNavigator I should change Drawer content for another Tab and lock DrawerLayout on some Tabs
I tried to do the same with DrawerNavigator with CustomLayout but I can't get current routeName in DrawerNavigator to change content based on Tab, I could use TabPress listener but then how I could update DrawerNavigator route from TabNavigator?
I am using DrawerLayout to set up Drawer for my react-native app. And I just wrap TabNavigator with DrawerLayout like that(pseudo code):
const TabNavigator = ({ route, navigation }) => {
return (
<DrawerLayout route={route} navigation={navigation}>
<Tab.Navigator>
<Tab.Screen>
...rest of tabs
</Tab.Navigator>
</DrawerLayout>
)
}
And I am navigation to another screen in DrawerLayout like this when user press on Item:
const onPressItem = () => {
// if Item is not selected then navigate to new screen in the same tab
if(TabSelectedItem !== 'New_Screen_In_The_Same_Tab') {
navigation.replace('New_Screen_In_The_Same_Tab')
navigation.setParams({
TabSelectedItem: 'New_Screen_In_The_Same_Tab',
})
}
// if tab was already selected close the drawer
closeDrawer()
}
So basically everything works except one thing, I noticed that if I just close DrawerLayout everythings is fine, but when I am navigating to new screen I feel like DrawerLayout is lagging, I suppose it could be because I do navigation and all TabNavigator do re-render
Question is:
Could I fix it, or better to use any another solutions for this specific case?

How to change headerStyle of Drawer Navigator based on Tab Navigator

I resolved this specific problem separating in different files the navigation components, with this way the component doesn't rerender anymore
First of all: i'm using React Native. I have a TabNavigator nested into a DrawerNavigator
i'm trying to change the color of the drawer header based on a specific screen into the Material Top Tab Navigator.
I tried to do it with screenListeners of the TabNavigator with a boolean state but when i made a setState the TabNavigator is rerendered and jump to the Home screen again.
PD: The App have a top header from the drawer and the bottom tab from the tabNavigator. I need that both of them change the color when X screen is focus.
To do this for the bottom tab i used route.name but i can't access to this property from the parent navigator.
....
screenOptions={({route}) => ({
tabBarStyle: {
backgroundColor:
route.name === '[targetScreen]' ? '#6600A1' : theme.PRIMARY_COLOR,
},
...
There are various options to provide a state in both directions, Redux, Recoil, Context Provider. If you are not already using one of them I think the Context Provider is the easiest. Basically it is a container around your outer navigator and inside you can access and change the state.

React navigation 5 bottom tab bar android keyboard ISSUE

There is huge problem with bottom tab navigation on android that I'm struggling with and can't find any solution!!
on Android when keyboard shows the bottom tab bar goes upon the keyboard, which is obviously not a desired behaviour!
This happens when softInputMode in Android Manifest is set to adjustResize (which is the default mode for react native), I've tried with adjustPan and resolves the problem, but now when keyboard appears android avoids not only the view but either the header of the app! This behaviour too is not acceptable!
I've also tried with workarounds like listening to keyboard events (didShow, and didHide are only available) and disabling the bottom bar on keyboard appearingt but this leads to many glitches in the app.
The keyboardHidesTabBar prop is also very ugly cause it is an animation that hides the bar that starts after keyboard opening...
Have you tried this solution keyboardHidesTabBar: true in TabBarOptions props.
<Tab.Navigator
tabBarOptions={{
keyboardHidesTabBar: true,
}}
>
<Tab.Screen />
<Tab.Screen />
</Tab.Navigator>
Answer for React Navigation V5 with or without a Custom tabBar
if you use a custom tabBar the keyboardHidesTabBar: true prop is not working but when i change the custom tabBar to default tab bar that prop works but i don't like the behavior of that prop on android, so i used keyboard from react-native to check if the keyboard is active or not and setting the css display prop to 'none'
import { Keyboard, View } from "react-native";
const [keyboardStatus, setKeyboardStatus] = useState<boolean>();
useEffect(() => {
const showSubscription = Keyboard.addListener('keyboardDidShow', () => {
setKeyboardStatus(true);
});
const hideSubscription = Keyboard.addListener('keyboardDidHide', () => {
setKeyboardStatus(false);
});
return () => {
showSubscription.remove();
hideSubscription.remove();
};
}, []);
so on the custom tab bar component now we can do like this.
<View style={
[
styles.mainContainer,
keyboardStatus ? styles.hideTabNavigation : null,
]
}
>
// your code here
</View>
Hope this will help someone until they fix this issue!

How to disable swipe action in specific screen on react navigation 5?

im using react navigation 5 on my project, and somewhere in the project i need to make nested navigators like below:
*Stack Navigator
**Material top tab navigatior
***Material bottom tab navigator
**** Stack Navigator
My goal is, actually i want to have 3 static screens like instagram. On the left side will be Camera, then in the center actual content and in the right side something else. And only when you are in center i want to bottom tabs are visible thats why i created it like that. In this case in all the screens you can swipe right or left for reaching to camera or right component.
But what i want to do is, i want do "disable" swipe action in detail screens in center component. Becose center component which is material bottom tab navigator above, contains some stack navigators also, like posts, postDetail. and when i go to postDetail i want to disable swipe left or right action. Becouse in some details im using some swipeable elements like react native swiper etc.
I have tried to give gesturesEnabled: false , swipeEnabled: false in material bottom navigator as props but it doesn't work becouse it's a bottom tab navigator and doesn't take these params.
I also tried to catch state index and if its greater than 0 or 1 i would disable it but in material top tab navigator doesn't change the index when i go to postDetail for example. It's not working like previous version which is react navigation 4.
const BlogStack = createMaterialTopTabNavigator();
const BlogStackNavigator = ({ navigation, route }) => {
return (
<BlogStack.Navigator
initialRouteName="Blogs"
tabBarOptions={{
style: {
height: 0,
},
}}
//swipeEnabled={route.state && route.state.index > 0 ? false : true}
>
<BlogStack.Screen name="Camera" component={Camera} />
<BlogStack.Screen name="Blogs" component={Blog} />
<BlogStack.Screen name="Timeline" component={Profile} />
</BlogStack.Navigator>
);
};
Try setting gestureEnabled to false in Screen's options.
<Screen name={key} options={{gestureEnabled: false}} component={Component} />
You need to set gestureEnabled to false but it's not sent as a prop. You need to set it in the options prop. If you want to set it for all screens you can place it in the navigator like this:
<BlogStack.Navigator
initialRouteName="Blogs"
tabBarOptions={{
style: {
height: 0,
},
}}
screenOptions={{gestureEnabled: false}}
>
or for only specific screens:
<BlogStack.Screen name="Camera" options={{gestureEnabled: false}} component={Camera} />

Can react navigation add costom button on the tab navigator like the pictures

I am facing a problem when using react-navigation. Is it possible to add a custom button on the tab navigator like the following pictures? Do you have any ideas on this? Thanks!!
After click the add button, then a modal pops and the tab navigator hides like:
You can put whatever you want in the bar by supplying your own implementation of the bar itself.
To use it, you'll have to set the tabBarComponent property on the TabNavigator configuration:
TabNavigator({
"Tab1": {screen: Tab1},
"Tab2": {screen: Tab2}
},
{
tabBarComponent: MyTabBar
})