React-Native Tab Navigation Bar cut off - android

I'm currently using the material-bottom-tabs to implement navigation in my mobile app.
For some odd reason, it isn't displayed correctly but cut off at the bottom of my screen.
This happens regardless of whether I activate gesture control (so the Android built-in navigation bar disappears) or not.
If I add padding to the style of my Tabs.Navigator, then the Tab-Navigation-Bar is still cut off, now by a white padding.
I tried to wrap my Tab.Navigator inside a SafeAreaView (from react-native-safe-area-context) but if I do this, I just get a plain white screen back.
This is my code:
import React, { Component } from 'react';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import DrawerHome from './DrawerHome';
import Bookmarks from './Bookmarks';
const Tab = createMaterialBottomTabNavigator();
const Stack = createStackNavigator();
//const insets = useSafeArea();
class App extends Component {
constructor(props) {
super(props);
this.state = {
userToken: 1, // set to 'null' in production state
};
}
render() {
return this.userToken === null ? (
<Stack.Screen name="LogIn" component={LoginScreen} />
) : (
<SafeAreaProvider>
<NavigationContainer>
<SafeAreaView>
<Tab.Navigator style={{ paddingBottom: '10%' }}>
<Tab.Screen
name="Current Schedule"
component={CarouselPage}
options={{
tabBarLabel: 'Current\nSchedule',
tabBarIcon: <Ionicons name="ios-calendar" size={20} />,
}}
/>
<Tab.Screen name="Resources" component={ResourceScreen} />
<Tab.Screen
name="Schedule Selection"
component={ScheduleSelectionScreen}
/>
<Tab.Screen name="About" component={AboutScreen} />
</Tab.Navigator>
</SafeAreaView>
</NavigationContainer>
</SafeAreaProvider>
);
}
}
export default App;
A screenshot of the display issue

Try this:
// ...
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="Current Schedule"
component={CarouselPage}
options={{
tabBarLabel: 'Schedule',
tabBarIcon: ({}) => (
<Ionicons name="ios-calendar" size={20} />
),
}}
/>
// ...
</Tab.Navigator>
</NavigationContainer>
// ...
The bar isn't cut off. The reason the text was cut off was, because you put a newline in the tabBarLabel text. I recommend to choose shorter words for your tab labels.
The documentation does not seem to provide an option to increase the padding for the label to allow for longer text.

Related

Navigation and Drawer Navigation React-Native

So I had a navigation system in place already, and wanted to add a Drawer menu for specific navigations starting on the main shopping page once the user had logged in. The issue I am having is after following some directions online on how to have multiple navigations of different types the drawer buttons just simply don't do anything when clicked on. any insight or help is much appreciated.
I have the NavigationContainer on the app.js file, containing the DrawerMenu file, through which I imported the main StackNavigator file.
Main StackNavigator file
// Main Nav
import PasswordVerify from '../screens/PasswordVerify';
import HomeShopping from '../screens/HomeShopping';
import StorePage from '../screens/StorePage';
// Drawer Screens
import ProfileScreen from '../screens/DrawerScreens/ProfileScreen';
import MyListingsScreen from '../screens/DrawerScreens/MyListingsScreen';
import SellerDashBoardScreen from '../screens/DrawerScreens/SellerDashBoardScreen';
const Stack = createNativeStackNavigator();
const Navigation = () => {
return (
<Stack.Navigator>
<Stack.Screen name="PasswordVerify" component={PasswordVerify} />
<Stack.Screen name="HomeShopping" component={HomeShopping} />
<Stack.Screen name="StorePage" component={StorePage} />
{/* Drawer Screens */}
<Stack.Screen name="ProfileIndex" component={ProfileScreen} />
<Stack.Screen name="MyListingsIndex" component={MyListingsScreen} />
<Stack.Screen name="SellerDashboardIndex" component={SellerDashBoardScreen} />
</Stack.Navigator>
DrawerMenu file
import { createDrawerNavigator } from '#react-navigation/drawer';
import Navigation from './StackNavigator';
const Drawer = createDrawerNavigator();
const DrawerMenu = () => {
return (
<Drawer.Navigator screenOptions={{headerShown: false}}>
<Drawer.Screen name="Profile" component={Navigation} />
<Drawer.Screen name="MyListings" component={Navigation} />
<Drawer.Screen name="SellerDashboard" component={Navigation} />
This is just what I interpreted from the guide I read and followed the best I could, and they had working examples, everything matches up except for the fact that when I pull out the Drawer menu, clicking the names there does nothing.
Thank you again for your time and help.
Tried implementing drawer navigation to my react-native app while I had another main navigation in place already for all non-drawer links. the result was the links on the drawer not responding at all.
I would understand your idea as follows:
You have 3 screens: PasswordVerify, HomeShopping, StorePage.
You have a Drawer with 3 screens: ProfileScreen, MyListingsScreen, SellerDashBoardScreen.
You want from PasswordVerify(or HomeShopping or StorePage) redirect to Drawer.
You want after redirect, you can see your drawer and can press(or slide) to display drawer menu.
And i have an idea for your case:
Define Drawer.
Use Drawer(defined) like a Stack.
Import Drawer in Stack.Navigator.
This is code:
const Drawer = createDrawerNavigator();
const DrawerNav = () => {
return (
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="ProfileScreen" component={ProfileScreen} />
<Drawer.Screen name="MyListingsScreen" component={MyListingsScreen} />
<Drawer.Screen name="SellerDashBoardScreen" component={SellerDashBoardScreen} />
</Drawer.Navigator>
);
};
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="PasswordVerify" component={PasswordVerify} />
<Stack.Screen name="HomeShopping" component={HomeShopping} />
<Stack.Screen name="StorePage" component={StorePage} />
<Stack.Screen name="DrawerNav" component={DrawerNav} />
</Stack.Navigator>
</NavigationContainer>
);
}

This is the best way to use Stack Navigator and Drawer Navigator together?

I've been programming in React Native for a short time, and I know little about react-navigation. After trying a lot I managed to use stack navigator with a custom drawer navigator (side menu), but this seems to be very strange because my stack is inside my menu drawer like a screen.
My stack:
const SignedInStack = () => (
<Stack.Navigator>
<Stack.Screen name='Confluence' component={Confluence} />
<Stack.Screen name='QRCode' component={Main} />
</Stack.Navigator>
)
In the DrawerMenu:
const DrawerMenu = () => (
<Drawer.Navigator
screenOptions={{ headerShown: false }}
drawerContent={(props) => <CustomDrawerContent {...props} />}
detachInactiveScreens={false}
>
<Drawer.Screen
name="SignedInStack"
component={SignedInStack}
options={{
drawerItemStyle: { height: 0 }
}}
/>
<Drawer.Screen
name="QRCode"
component={Main}
/>
<Drawer.Navigator/>
);
In the App.js:
const App = () => (
<NavigationContainer>
<DrawerMenu />
</NavigationContainer>
);
Previously I use my drawer menu inside my stack, but the app had navigation problems.

Left-to-right animation on Android with react-native-navigation when pushing new screen to stack

On Android with react-native-navigation, when pushing a new screen to the stack, I’d like the transition animation to be from left-to-right (or vice-versa, for RTL layout)
In iOS it‘s the default, where as on Android – it seems to be shown with cross-dissolve animation. how can I achieve the horizontal animation as in iOS?
Here is an example stack navigator for you:
import { createStackNavigator, CardStyleInterpolators } from "#react-navigation/stack";
class CompaniesIndex extends React.Component<
ICompaniesIndexProps,
ICompaniesIndexState
> {
render() {
return (
<CompanyStack.Navigator
mode="modal"
screenOptions={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS
}}
initialRouteName="AllCompanies">
<CompanyStack.Screen
options={{
title: "Firma Listesi",
header: (props) => <Header {...props} />,
}}
name="AllCompanies"
component={CompaniesAll}
/>
<CompanyStack.Screen
options={{
title: "Yeni Firma",
header: (props) => <Header {...props} />,
}}
name="NewCompany"
component={CompanyNew}
/>
<CompanyStack.Screen
options={{
title: "Firma Detayı",
header: (props) => <Header {...props} />,
}}
name="CompanyDetails"
component={CompanyDetails}
/>
</CompanyStack.Navigator>
);
}
}
You can achieve that with adding screenOptions={{cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS}} in your stack navigator.
For react-navigation#6.0.1, use animation: "slide_from_right" in screenOptions.
<Stack.Navigator
screenOptions={{
headerShown: false,
animation: "slide_from_right",
}}
if you use native-stack (#react-navigation/native-stack or react-native-screens/native-stack), just input 'stackAnimation' option in screenOptions of your Navigator!
import { createNativeStackNavigator } from 'react-native-screens/native-stack';
const Stack = createNativeStackNavigator();
<Stack.Navigator screenOptions={{ headerShown: false, stackAnimation: 'slide_from_right' }}>
<Stack.Screen name="First" component={FirstScreen} />
<Stack.Screen name="Second" component={SecondScreen} />
</Stack.Navigator>

drawer-navigation doesn't hide screen

I am using react-navigation 5 and I have stack navigation and inside drawer navigation, I want to hide some of the drawer's navigation screens. So, I pass null in drawerLabel attribute as follow
import * as React from 'react';
import {createDrawerNavigator} from '#react-navigation/drawer';
import ShowNotes from "../screens/notes/ShowNotes";
const Drawer = createDrawerNavigator();
const DrawerNavigation = () => {
return (
<Drawer.Navigator>
<>
<Drawer.Screen
name="Home"
component={ShowNotes}
options={{
headerTitle: 'All Notes',
drawerLabel: () => null
}}
/>
</>
</Drawer.Navigator>
);
}
export default DrawerNavigation;
This DrawerNavigation is inside a StackNavigation like so
const Stack = createStackNavigator();
const Navigation = ({auth}) => {
return (
<NavigationContainer theme={CustomTheme}>
<Stack.Navigator
screenOptions={({navigation}) => ({
headerLeft: () => (
<Button
onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
title="Info"
color="#fff"
/>
),
})}
>
<Stack.Screen
name="Home"
component={DrawerNavigation}
/>
<Stack.Screen
name="AddNoteScreen"
component={AddNote}
/>
<Stack.Screen
name="UpdateNoteScreen"
component={UpdateNote}
/>
}
</Stack.Navigator>
</NavigationContainer>
);
};
const mapStateToProps = state => {
return {auth: state.auth};
};
export default connect(mapStateToProps, {})(Navigation);
What I see on my screen is the drawer doesn't contain my screen but an empty blank area which is clickable
How I can stop displaying a screen in drawer?
Cheers
I don't know if this is the best solution but this is what it works for me.
I set the screens that I don't want to display as Drawer.Screen and inside Drawer.Navigator I set the property drawerContent with the screens that I want to display in the drawer. have a look in the code
<Drawer.Navigator
drawerContent={() => {
return (
<>
<DrawerContentScrollView>
{auth.isSignedIn ?
<Layout>
<Layout>
<Layout style={{flexDirection: 'row', marginTop: 15, marginLeft: 10}}>
<Avatar.Image
source={{
uri: auth.userData.picture,
}}
size={70}
/>
<Layout style={{flexDirection: 'column', marginLeft: 15}}>
<Title>{auth.userData.name}</Title>
<Caption>{auth.userData.email}</Caption>
</Layout>
</Layout>
</Layout>
</Layout>
:
<>
</>
}
</DrawerContentScrollView>
<DrawerSection>
<DrawerItem
icon={({color, size}) => (
<Icon
name="exit-to-app"
color={color}
size={size}
/>
)}
label="Sign Out"
onPress={() => {
LoginManager.logOut();
signOut();
}}
/>
</DrawerSection>
</>
);
}}
>
<
Drawer.Screen
name="Home"
component={ShowNotes}
options={
{
headerTitle: 'All Notes',
}
}
/>
<Drawer.Screen
name="AddNoteScreen"
component={AddNote}
/>
<Drawer.Screen
name="UpdateNoteScreen"
component={UpdateNote}
/>
</Drawer.Navigator>
I hope it helps!

How to pass navigator to hamburger menu component?

I'm trying to implement a custom navigation drawer using react-navigation and react-native-elements. I also want all my screens to have a header (that has a hamburger from which I can control the drawer). The problem I'm facing is that the screen includes the header, while the drawer includes the screen, yet the header needs the drawer for its click event. So how do I pass the drawer object to my hamburger (inside the header component)?
The header in the file UniversalHeader.js is as follows
export default class UniversalHeader extends React.Component {
render() {
return (
<Header
leftComponent={{ icon: 'menu', color: '#ea0', onPress: () => this.props.navigation.navigate('DrawerToggle'), size: 50}}
centerComponent={{ text: this.props.label, style: { color: '#fff' } }}
/>
);
}
}
In my home screen, I have
import UniversalHeader from './UniversalHeader'
export default class HomeScreen extends React.Component {
render() {
return (
<View>
<UniversalHeader />
<Text> cards go here </Text>
</View>
);
}
}
Then in the compiling script collating the screens, I have
import HomeScreen from './home';
class customNav extends React.Component {
render() {
return (
<View>
<Avatar rounded xlarge source={require('./images/logo.png')} />
<DrawerNavigatorItems navigation={{state: [{routeName: 'Home', key: '0'}]}}
items={['Home', 'Discussions', 'Podcasts', 'Sermons', 'Events']}
onItemPress={route => this.props.navigation.navigate(route)}
renderIcon={(routeIcon) => (
<Image source={{uri: `./images/${routeIcon}.png`}} style={[styles.icon, {/*tintColor: tintColor*/}]} />
)}
getLabel={route => route.toString()}
/>
</View>
)
}
}
const MyApp = DrawerNavigator({
Home: {
screen: HomeScreen
}
}, {drawerBackgroundColor: '#000', contentComponent: customNav});
The onPress method in Header leftComponent has no idea of who navigator is but I don't know how to get it across either from the screen 'home.js' or from the 'UniversalHeader.js'.
The navigation property is automatically added to every component passed as a screen to any react-navigation component. So by proactively passing this.props.navigation of homescreen component to universalHeader i.e
<UniversalHeader navigation={this.props.navigation} />
You'll be giving it the navigator that's aware of all your registered classes/screen (in this case, passed into DrawerNavigator)

Categories

Resources