Why my panel is hiding the body of my views? - react-native

i want to build a built a navigation with BottomTabNavigator but i dont know what happen i never see the body of my screens, something is hidding the body, i created a demo to demostrate you the wrong, but its too simple.
this is the file App.js
import React from 'react'
//import { Provider } from 'react-native-paper'
import { Provider, useSelector } from 'react-redux'
import { createStore } from 'redux'
import { NavigationContainer } from '#react-navigation/native'
import { View, Text } from 'react-native'
import { createStackNavigator } from '#react-navigation/stack'
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs'
const Stack = createStackNavigator()
function HomeScreen() {
return (
<View
style={{
flexDirection: 'row',
height: 100,
padding: 20,
}}
>
<View style={{ backgroundColor: 'blue', flex: 0.3 }} />
<View style={{ backgroundColor: 'red', flex: 0.5 }} />
<Text>Hello World!</Text>
</View>
)
}
function SettingsScreen() {
return (
<View
style={{
backgroundColor: 'red',
flex: 1,
color: 'green',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text>Settings!</Text>
</View>
)
}
const Tab = createBottomTabNavigator()
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="main">
<Stack.Screen name="loginScreen" component={SettingsScreen} />
<Stack.Screen name="main" component={MyTabs} />
</Stack.Navigator>
</NavigationContainer>
)
}
i am trying to do, before to user is logged i would like to hidde the tabs
something is hidding
edit 1: why i have 2 headers?

On the web, #react-navigation/bottom-tabs mistakenly treat screens in the tab as inactive and detaches them.
The solution is to disable detach inactive screens for bottom tab.
import React from "react";
//import { Provider } from 'react-native-paper'
import { Provider, useSelector } from "react-redux";
import { createStore } from "redux";
import { NavigationContainer } from "#react-navigation/native";
import { View, Text } from "react-native";
import { createStackNavigator } from "#react-navigation/stack";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
const Stack = createStackNavigator();
function HomeScreen() {
return (
<View
style={{
flexDirection: "row",
height: 100,
padding: 20,
}}
>
<View style={{ backgroundColor: "blue", flex: 0.3 }} />
<View style={{ backgroundColor: "red", flex: 0.5 }} />
<Text>Hello World!</Text>
</View>
);
}
function SettingsScreen() {
return (
<View
style={{
backgroundColor: "red",
flex: 1,
color: "green",
justifyContent: "center",
alignItems: "center",
}}
>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator detachInactiveScreens={false}>
<Tab.Screen name="Home" component={HomeScreen} options={{headerShown:false}} />
<Tab.Screen name="Settings" component={SettingsScreen} options={{headerShown:false}}/>
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="main" >
<Stack.Screen name="loginScreen" component={SettingsScreen} options={{headerShown:false}}/>
<Stack.Screen name="main" component={MyTabs} options={{headerShown:false}} />
</Stack.Navigator>
</NavigationContainer>
);
}

Moving between screens
You can create a state for handling user logged in status or you can also use redux for it so It will automatically navigate to the main screen after user logged in
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
{state.userToken == null ? (
// No token found, user isn't signed in
<Stack.Screen name="loginScreen" component={LoginScreen} />
) : (
// User is signed in
<Stack.Screen name="main" component={MyTabs} />
)}
</Stack.Navigator>
</NavigationContainer>
);
}
More details Here

Related

What is the proper way to have only one header with Open Drawer and Back button?

What I need is a single header with a back button on StackScreen2 and a toggle drawer button in StackScreen1.
I apologise for my poor writing and English.
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function StackScreen1({ navigation }) {
return (
<View>
<Text>StackScreen1</Text>
<Button title="Go To StackScreen2" onPress={() => navigation.navigate("StackScreen2")} />
</View>
)
}
function StackScreen2() {
return (
<View>
<Text>StackScreen2</Text>
</View>
)
}
function DrawerScreen1() {
return (
<Stack.Navigator>
<Stack.Screen name="StackScreen1" component={StackScreen1} />
<Stack.Screen name="StackScreen2" component={StackScreen2} />
</Stack.Navigator>
)
}
function DrawerScreen2() {
return (
<View>
<Text>DrawerScreen2</Text>
</View>
)
}
const Drawer = createDrawerNavigator();
export default function Test3() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="DrawerScreen1" component={DrawerScreen1} />
<Drawer.Screen name="DrawerScreen2" component={DrawerScreen2} />
</Drawer.Navigator>
</NavigationContainer>
);
}
StackScreen1
StackScreen2
I tried hiding drawer header but then I don't have toggle drawer button anywhere.
Check below code for drawer navigation:
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator useLegacyImplementation initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
You can check more about drawer here.
May be this will help you!
import * as React from 'react';
import { Ionicons, FontAwesome } from '#expo/vector-icons';
import { Button, View, Text, Pressable,Image } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createDrawerNavigator } from '#react-navigation/drawer';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('SettingsScreen')}
/>
</View>
);
}
function DetailsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.goBack()}
/>
</View>
);
}
const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
<Drawer.Navigator
useLegacyImplementation
// screenOptions={{
// drawerLabelStyle: { fontSize: 17, color: '#000',marginLeft:-30 }
// }}
>
<Drawer.Screen
name="HomeScreen"
component={DetailsScreen}
screenOptions={{
headerShown: false,
}}
/>
</Drawer.Navigator>
);
}
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen
name="SettingsScreen"
component={MyDrawer}
options={{
headerShown: false,
tabBarIcon: ({ color, size }) => (
<Ionicons name="md-home" size={24} color={'#eee'} />
),
tabBarStyle: { position: 'absolute' },
tabBarActiveTintColor: '#eee',
tabBarInactiveTintColor: '#eee',
}}
/>
<Tab.Screen
name="DetailsScreen"
component={DetailsScreen}
options={{
headerShown: false,
tabBarIcon: ({ color, size }) => (
<Image source={{uri:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUAN0zLcvLFjdaYN1dBRSKoIuJndRW6VuX85w2yzEzxvTwO3B0Y_gv1x8kVDISNKJEbq0&usqp=CAU"}}
style={{width:24,height:24,borderRadius:24}} />
),
tabBarStyle: { position: 'absolute' },
tabBarActiveTintColor: '#eee',
tabBarInactiveTintColor: '#eee',
}}
/>
</Tab.Navigator>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>2</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="HomeScreen">
<Stack.Screen
name="HomeScreen"
component={HomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="SettingsScreen"
component={MyTabs}
options={{ headerShown: false }}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;

How to make headerTitle to fit into headerBackground with react navigation?

I am using the react navigation library with react native, I want to create a custom header by using the headerBackground and headerTitle screen options.
I need a robust way for the headerTitle component to use all the available space, but remains inside the limits of the screen.
So far I have (Snack link):
function App(): JSX.Element {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
options={{
headerBackground: () => (
<View
style={{
flex: 1,
backgroundColor: 'red',
borderColor: 'green',
borderWidth: 4,
}}
/>
),
headerTitle: props => (
<View
style={{
backgroundColor: 'blue',
flex: 1,
}}>
<Text>Header Title</Text>
</View>
),
}}>
{() => <SafeAreaView />}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
);
}
Note I have inlined styles and other bad practices just to make the code shorter for this question.
The results is the following:
Note how the headerTitle component grows without limits.
Is there a robust way to deal with this issue ? Note I am trying to avoid getting/using the dimensions of the device, as in the header can be other content such as backButton, or other options buttons on the right side.
Thanks in advance.
here is code example you can see to run this code may be this will help you:)
App.js
import * as React from 'react';
import {
Button,
View,
Text,
ImageBackground,
StyleSheet,
TouchableOpacity,
Image
} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
const image = { uri: 'https://reactjs.org/logo-og.png' };
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function DetailsScreen({ navigation }) {
return (
<View style={{}}>
<ImageBackground source={image} style={styles.image}>
<TouchableOpacity
onPress={()=>navigation.navigate("Home")}
>
<Image source={{uri:"https://cdn-icons-png.flaticon.com/128/189/189254.png"}} style={{width:30,height:30,marginLeft:10,marginTop:20}}/>
<Text style={{fontSize:30 ,color:'white',textAlign:'center',fontWeight:'bold',marginTop:-40}}> hello world</Text>
</TouchableOpacity>
</ImageBackground>
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerShown: false,
}}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
image: {
width: "100%",
height: 60,
},
text: {
color: 'white',
fontSize: 42,
lineHeight: 84,
fontWeight: 'bold',
backgroundColor: '#000000c0',
},
});
export default App;

React Native Expo app showing two topbars

I'm following this example: https://reactnavigation.org/docs/tab-based-navigation#a-native-stack-navigator-for-each-tab
I've copy pasted the example from the website. However, this is what I see:
I've the following packages in package.json:
"#react-navigation/bottom-tabs": "^6.0.9",
"#react-navigation/native": "^6.0.6",
"#react-navigation/native-stack": "^6.2.5",
"#react-navigation/stack": "^6.0.11",
Here's my code:
import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import Ionicons from '#expo/vector-icons/Ionicons';
function DetailsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function AnalyticsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Analytics screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
const HomeStack = createNativeStackNavigator();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="HomeScreen" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
</HomeStack.Navigator>
);
}
const SettingsStack = createNativeStackNavigator();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="SettingsScreen" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}
const AnalyticsStack = createNativeStackNavigator();
function AnalyticsStackScreen() {
return (
<AnalyticsStack.Navigator>
<AnalyticsStack.Screen name="Analytics" component={SettingsScreen} />
<AnalyticsStack.Screen name="Details" component={DetailsScreen} />
</AnalyticsStack.Navigator>
)
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = 'home';
} else if (route.name === 'Settings') {
iconName = 'search';
} else if (route.name === 'Analytics') {
iconName = 'bar-chart'
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: 'tomato',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
<Tab.Screen name="Analytics" component={AnalyticsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
You can easily hide navigator headers like this:
<YourNavigator.Navigator
screenOptions={{ headerShown: false /* <-- This will hide your header */ }}
>
<YourNavigator.Screen
name='Settings' /* <-- This name will be shown as header if true */
component={YourSettingsNavigator}
/>
</YourNavigator.Navigator>
Since YourSettingsNavigator is another Navigator, you are nesting navigators in each other. When doing this make sure to set headerShown: false in at least one of the navigators or you get two headers.

How to put picker component inside a page that have a tab navigator in React Native

i need some help. I am new to Native React. I have a created a tab navigator in react native. I would like to put a picker in one of the pages. But i am not too sure how to do it. I have both code on my Tab navigator and a code for picker as well.
My codes for Tab navigator:
import React, {Component} from 'react';
import { Text, View, Button, TextInput, StyleSheet, Picker} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createStackNavigator } from '#react-navigation/stack';
import Ionicons from 'react-native-vector-icons/Ionicons';
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: 'black',
inactiveTintColor: 'gray',
}}
>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
function DetailsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}
function HomeScreen({ navigation }) {
const [value, onChangeText]= React.useState('')
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Tab 1</Text>
<TextInput style={{height: 40, borderColor:'black', borderWidth: 1, color: 'red', borderRadius:10}} placeholder="Type Here" onChangeText={text => onChangeText(text)} value={value}/>
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')}
/>
</View>
);
}
function SettingsScreen({navigation}) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Tab 2</Text>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
</View>
);
}
const HomeStack = createStackNavigator();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
</HomeStack.Navigator>
);
}
const SettingsStack = createStackNavigator();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}
My Code for a picker(simple)
import React, {Component} from 'react';
import { Text, View, Button, TextInput, StyleSheet, Picker} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createStackNavigator } from '#react-navigation/stack';
import Ionicons from 'react-native-vector-icons/Ionicons';
import RNPPickerSelect from 'react-native-picker-select';
export default class SwitchExample extends Component {
state = {
choosenIndex: 0
};
render() {
return (
<View style={styles.container}>
<Text style={styles.textStyle}>Picker Example</Text>
<Picker style={styles.pickerStyle}
selectedValue={this.state.language}
onValueChange={(itemValue, itemPosition) =>
this.setState({language: itemValue, choosenIndex: itemPosition})}
>
<Picker.Item label="Java" value="java" />
<Picker.Item label="JavaScript" value="js" />
<Picker.Item label="React Native" value="rn" />
</Picker>
<Text style={styles.textStyle}> {"Index ="+this.state.choosenIndex}</Text>
</View>
);
}
}
const styles = StyleSheet.create ({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
textStyle:{
margin: 24,
fontSize: 25,
fontWeight: 'bold',
textAlign: 'center',
},
pickerStyle:{
height: 150,
width: "80%",
color: '#344953',
justifyContent: 'center',
}
})

How can I access a current navigation inside a React.Component using reactnavigation 5?

I'm now using react-navigation version 5 following an expo tutorial to navigate to another screen inside a Stack (embedded in a Tab Navigator).
In the tutorial, they always used a function to init a specific screen so the navigation parameter will easy to be called inside the function's body.
Eg:
function HomeScreen({ navigation })
//Called
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
But, if I construct a React.Component instead, how can I access the navigation inside that Component to navigate to another component? plz
Please run the codes bellow on expo if my explanations are bad.
Thanks,
import * as React from 'react';
import { Button, Text, View, Alert } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
class Options extends React.Component {
navigaeToAnotherScreen() {
console.log('How can I access current navigation plz?');
}
render() {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Hello, world! Option</Text>
<Button title="Go To Main" onPress={() => this.navigaeToAnotherScreen() }/>
</View>
);
}
}
function OptionsScreen({ navigation }) {
return (
<Options/>
);
}
function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
<Button title="Detail" onPress={ () => navigation.push('Options')}/>
</View>
);
}
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.push('Details')}
/>
</View>
);
}
const HomeStack = createStackNavigator();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
<HomeStack.Screen name="Options" component={OptionsScreen} />
</HomeStack.Navigator>
);
}
const SettingsStack = createStackNavigator();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
try this
I noticed you didn't pass existing props to Options
function OptionsScreen({ navigation }) {
return (
<Options navigation={navigation} />
);
then try this
navigaeToAnotherScreen() {
this.props.navigation.navigate("AnyScreen");
}