I'm making a music app and what I want to do is to implement a music player screen that can be active on all other screens something like this:
https://reactnativeexample.com/react-native-swipe-up-down-component/
This is my app.js:
import React, {Component} from 'react';
import { createDrawerNavigator, createStackNavigator, createAppContainer } from "react-navigation";
import HomeScreen from './screens/home';
import SideBar from './screens/sidebar';
import SongScreen from './screens/song';
const Drawer = createDrawerNavigator(
{
Home: {screen: HomeScreen}
},
{
initialRouteName: "Home",
contentOptions: {
activeTintColor: "#e91e63"
},
contentComponent: props => <SideBar {...props} />
}
);
const AppNavigator = createStackNavigator(
{
Drawer: { screen: Drawer },
SongScreen: { screen: SongScreen }
},
{
initialRouteName: "Drawer",
headerMode: "none"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default class App extends Component {
render() {
return (
<AppContainer />
);
}
}
use https://github.com/octopitus/rn-sliding-up-panel and make your root screen look like this:
<View>
<AppContainer/>
<SlidingUpPanel/>
</View
Related
I have my next splash, my idea is to be able to show my app logo when opening the application and then go to the start of the application, it works fine:
import React from 'react';
import { StyleSheet, Image, View, Text } from 'react-native';
import { StackActions, NavigationActions } from 'react-navigation';
export default class Splash extends React.Component {
goToScreen(routeName){
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: routeName })],
});
this.props.navigation.dispatch(resetAction);
}
/*goToScreen(routeName){
this.props.navigation.navigate(routeName)
}*/
componentDidMount(){
setTimeout( () => {
this.goToScreen('Home')
}, 2000, this)
}
render(){
return (
<View style={styles.container}>
<Image source={{uri: 'https://i.imgur.com/r0jUwOD.png'}} style={{width: 250, height: 250}} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#33B747',
alignItems: 'center',
justifyContent: 'center'
},
});
The problem is the location of the splash, since in this way if it shows me, but it creates a lower button called Splash, on the other hand the splash when loading is shown in conjunction with the lower buttons and that should not happen, the splash must display only in full screen and not create a button.
AppNavigator.js
import React from 'react';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { createAppContainer } from 'react-navigation';
import { MaterialIcons, MaterialCommunityIcons } from '#expo/vector-icons';
import Splash from '../screens/Splash';
import NewsListScreen from '../screens/NewsListScreen';
import NewsItemScreen from '../screens/NewsItemScreen';
const StackNavigator = createStackNavigator({
Splash: {
screen: Splash,
navigationOptions: {
headerShown: false,
}
},
News: {
screen: NewsListScreen
},
Root: {
screen: BottomTabNavigator,
},
NewsItem: {
screen: NewsItemScreen,
navigationOptions: {
headerTitle: 'News Item'
}
},
},{
initialRouteName: 'Splash'
});
const BottomTabNavigator = createBottomTabNavigator({
Home: {
screen: StackNavigator,
navigationOptions: {
tabBarIcon: () => <MaterialIcons name="home" size={24} />
}
},
News: {
screen: StackNavigator,
navigationOptions: {
tabBarIcon: () => <MaterialCommunityIcons name="newspaper-variant-outline" size={24} />
}
}
})
export default createAppContainer(BottomTabNavigator);
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { AppLoading } from 'expo';
import { Provider } from 'react-redux';
import AppNavigator from './app/resources/navigation/AppNavigator';
import ReduxStore from './app/resources/redux/ReduxStore';
export default function App() {
return (
<Provider store={ReduxStore}>
<AppNavigator />
</Provider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Attached capture of the error upload in imgur capture 1 and capture 2
The recommended way to add a splash screen to an expo managed app can be found here.
I've managed to create an expo project and achieve the exact same behavior that you've looking for.
I've used react-navigation 4.x.x
This is how it looks and you can find the full code here
Here is the code I've used.
Splash.js
import React, { Component } from "react";
import { Text, SafeAreaView, View, StyleSheet } from "react-native";
import { StackActions, NavigationActions } from "react-navigation";
export class Splash extends Component {
goToScreen(routeName) {
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: routeName })],
});
this.props.navigation.dispatch(resetAction);
}
componentDidMount() {
setTimeout(
() => {
this.goToScreen("Root");
},
2000,
this
);
}
render() {
return (
<SafeAreaView style={styles.mainContainer}>
<Text style={styles.text}> Splash Screen </Text>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#efef21",
},
text: {
fontSize: 22,
},
});
export default Splash;
Navigator.js
import { createStackNavigator } from "react-navigation-stack";
import { createAppContainer } from "react-navigation";
import Home from "./Home";
import Splash from "./Splash";
import TabNavigator from "./BottomTabNavigator";
const AppNavigator = createStackNavigator(
{
Splash: {
screen: Splash,
navigationOptions: {
headerShown: false,
},
},
Root: {
screen: TabNavigator,
navigationOptions: {
headerShown: false,
},
},
},
{
initialRouteName: "Splash",
}
);
export default createAppContainer(AppNavigator);
BottomTabNavigator.js
import { createAppContainer } from "react-navigation";
import { createBottomTabNavigator } from "react-navigation-tabs";
import Home from "./Home";
import News from "./News";
const TabNavigator = createBottomTabNavigator({
Home: {
screen: Home,
navigationOptions: {
title: "Home",
},
},
News: {
screen: News,
navigationOptions: {
title: "News",
},
},
});
export default createAppContainer(TabNavigator);
Also, I've achieved the same behavior using react-navigation 5.x.x
You can find my code here
Edit 01
If you want to have the headers, You need to use a Stack Navigator for each tab.
Here is the updated code of BottomTabNAvigator.js
import { createAppContainer } from "react-navigation";
import { createBottomTabNavigator } from "react-navigation-tabs";
import { createStackNavigator } from "react-navigation-stack";
import Home from "./Home";
import News from "./News";
const HomeStack = createStackNavigator({
Home: Home,
});
const NewsStack = createStackNavigator({
News: News,
});
const TabNavigator = createBottomTabNavigator({
Home: {
screen: HomeStack,
navigationOptions: {
headerTitle: "Home",
title: "Home",
},
},
News: {
screen: NewsStack,
navigationOptions: {
title: "News",
},
},
});
export default createAppContainer(TabNavigator);
You have used Splash: {screen: Splash}, in your BottomTabNavigator so obviously it will add splash as on bottom navigator.
Remove Splash: {screen: Splash}, from BottomTabNavigator and paste it on StackNavigator and set splash as initialRouteName
const StackNavigator = createStackNavigator({
News: {
screen: NewsListScreen
},
Splash: {screen: Splash},
NewsItem: {
screen: NewsItemScreen,
navigationOptions: {
headerTitle: 'News Item'
}
},
},
{
initialRouteName : 'Splash'
});
you have to move splash screen to StackNavigator and add BottomTabNavigator into StackNavigator as a screen like this
import React from 'react';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { createAppContainer } from 'react-navigation';
import { MaterialIcons } from '#expo/vector-icons';
import Splash from '../screens/Splash';
import NewsListScreen from '../screens/NewsListScreen';
import NewsItemScreen from '../screens/NewsItemScreen';
const StackNavigator = createStackNavigator({
Splash: {
screen: Splash
},
Home: {
screen: BottomTabNavigator
},
News: {
screen: NewsListScreen
},
NewsItem: {
screen: NewsItemScreen,
navigationOptions: {
headerTitle: 'News Item'
}
}
},
{
initialRouteName: "Splash",
});
const BottomTabNavigator = createBottomTabNavigator({
Home: {
screen: StackNavigator,
navigationOptions: {
tabBarIcon: () => <MaterialIcons name="home" size={24} />
}
}
})
export default createAppContainer(StackNavigator);
I create two tabs.
Here is my react-navigation configure setting:
navigator/index.ts
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import RootScreen from '../components/RootScreen';
import MainStack from './MainStack';
const RootStack = createSwitchNavigator(
{
RootScreen: RootScreen,
MainStack: MainStack
},
{
initialRouteName: 'RootScreen',
}
)
const AppContainer = createAppContainer(RootStack);
export default AppContainer;
navigator/MainStack.ts
import { createStackNavigator } from 'react-navigation-stack';
import TabsStack from './TabsStack'
const MainStack = createStackNavigator(
{
tabs: TabsStack,
},
{
// headerMode: 'none',
}
);
export default MainStack;
navigator/TabsStack.tsx
import React from 'react';
import { Image } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import HomeScreen from '../components/HomeScreen/HomeScreen';
import SettingScreen from '../components/SettingScreen/SettingScreen';
import LoveIcon from '../assets/image/heart.png';
const TabsStack = createBottomTabNavigator(
{
HomeScreen: {
screen: HomeScreen,
navigationOptions: {
title: 'Home',
tabBarLabel: 'HomeTab',
tabBarIcon: ({ focused, tintColor }) => {
return <Image {...with some props}/>
},
}
},
SettingScreen: {
screen: SettingScreen,
navigationOptions: {
tabBarLabel: 'STab',
tabBarIcon: ({ focused, tintColor }) => {
return <Image {...with some props}/>
},
}
},
},
{
tabBarOptions: {
showLabel: true,
activeTintColor: 'blue',
inactiveTintColor: 'black',
style: {
// with some style
}
},
}
);
export default TabsStack;
And I try to set header title on my HomeScreen.tsx by using static navigationOptions
import React from 'react';
import { View, Text } from 'react-native';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'HomeScreen Header',
};
render() {
return (
<View>
<Text>I am HomeScreen</Text>
</View>
);
}
}
export default HomeScreen;
My HomeScreen header shows tabs.
It looks like static navigationOptions is not working.
What's wrong with my react-navigation settings ?
Just use this way:
import React from 'react';
import { View, Text } from 'react-native';
class HomeScreen extends React.Component {
componentDidMount() {
this.props.navigation.setOptions({ title: 'HomeScreen Header' });
};
render() {
return (
<View>
<Text>I am HomeScreen</Text>
</View>
);
}
}
export default HomeScreen;
Environment
React native: 0.61
react-native navigation:4.0
Deployed os : Android 9 pie
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import Signup from './Signup';
import React, { Component } from 'react';
import Home from './Home';
import EditProfile from './Editprofile';
import Payments from './Payments';
import Refer from './Refer';
import { createDrawerNavigator } from 'react-navigation-drawer';
export default class App extends React.Component {
render() {
return <Appcont />;
}
}
const appi = createStackNavigator(
{
signup: {
screen: ()=><Signup/>
},
home: {
screen: ()=><Home/>
},
editProfile:{
screen:()=><EditProfile/>
},
payments:{
screen:()=><Payments/>
},
refer:{
screen:()=><Refer/>
}
},
{
initialRouteName:'signup'
}
);
const MyDrawerNavigator = createDrawerNavigator(appi,{
initialRouteName: 'signup',
headerMode:'float',
contentOptions: {
activeTintColor: '#e91e63',
}
});
const Appcont = createAppContainer(MyDrawerNavigator);
home.js
import React, { Component } from 'react';
import { Text, View,Image } from 'react-native';
class Home extends Component {
static navigationOptions = {
title:'Home',
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<Image
source={require('./img/Homepng.png')}
style={{width:20,height:20}}
/>
),headerShown:'true'
};
render() {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Hello, home</Text>
</View>
);
}
}
export default Home;
When I run the above code it throws me an error !!!
Error The component for the router must be a react component
I have seen all the issues related to this and rectified as much I can but I am still getting this error I don't know why?
you can try to change the
const appi = createStackNavigator(
{
signup: {
screen: ()=><Signup/>
},
}
to
const appi = createStackNavigator({
signup: {
screen: Signup,
},
});
At the same time ,the Singup have to extend React.Component, and remember export it. and () => <Home/> is not a component. it is function object
export defalut class Sigup extends React.component
I am trying to navigate to a screen that I have not defined with createBottomTabNavigation as I don't want it to be shown on the bottom tab navigation.
To try so I have created the component separately:
class SingleScreen extends React.Component {
render() {
return (
<View>
<Text>This is sigle screen</Text>
</View>
);
}
}
To navigate to this screen:
render () {
const {navigate} = this.props.navigation;
return(
<TouchableHighlight onPress={() => navigate('SingleScreen', {id: 'id', from: 'Search'})}>
//Code
</TouchableHighlight>
);
}
But is not working. Do I have to describe this screen with createBottomTabNavigator? If so, is it possible to hide from appearing on the tab bar?
You need to make some change in app.js. add createBottomTabNavigator inside createStackNavigator. Add those component into stacknavigator in which you do not want to add into bottom tab navigator. In createBottomTabNavigator add those component which you want to show in tab bar
Please check following code
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
SafeAreaView,
ScrollView,
Dimensions
} from "react-native";
import { createStackNavigator, createDrawerNavigator } from "react-navigation";
import LoginScreen from "./Screens/LoginScreen";
export default class App extends Component {
render() {
return <StackNav />;
}
}
const StackNav = createStackNavigator(
{
TabNavigator: {
screen: AppTabNavigator,
navigationOptions: {
headerMode: "none",
header: null
}
},
SingleScreen: {
screen: SingleScreen,
navigationOptions: {
headerMode: "none",
header: null
}
},
SecondScreen: {
screen: SecondScreen,
navigationOptions: {
headerMode: "none",
header: null
}
}
},
{
initialRouteName: "TabNavigator"
}
);
const AppTabNavigator = createBottomTabNavigator({
Login: {
screen: LoginScreen
}
});
recently I have a problem on a simple DrawerNavigator inside StackNavigator. My goal is to get both the back function from StackNavigator and DrawerNavigator side menu when I click BurgerMenu icon on the StackNavigator's header.
Here's my current code
import React, { Component } from 'react';
import { TouchableHighlight } from 'react-native';
import SvgUri from 'react-native-svg-uri';
import { StackNavigator } from 'react-navigation';
import { DrawerNavigator } from "react-navigation";
import SideBar from './SideBar';
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import Screen3 from './Screen3';
export default class App extends React.Component {
render() {
return <StackNav />;
}
}
class BurgerMenu extends React.Component {
render() {
return (
<TouchableHighlight
onPress={() => this.props.navigation.navigate("DrawerOpen")}>
<SvgUri
width="30"
height="30"
source={require("Project_01/app/images/menu.svg")}
/>
</TouchableHighlight>
);
}
}
const DrawerNav = DrawerNavigator(
{
Screen1: { screen: Screen1 }
},
{
contentComponent: props => <SideBar {...props} />
}
);
const StackNav = StackNavigator(
{
Screen1: {
screen: DrawerNav,
},
Screen2: {
screen: Screen2,
},
Screen3: {
screen: Screen3,
},
},
{
initialRouteName: 'DrawerNav',
navigationOptions: {
headerRight: <BurgerMenu /> ,
title: "Header"
},
},
);
As you can see Im adding headerRight with BurgerMenu component to navigationOptions in StackNavigator.
In BurgerMenu class I added TouchableHighlight with " onPress={() => this.props.navigation.navigate("DrawerOpen")}> " which I mean open up the DrawerNavigator.
Unfortunately when I press that, i got an error message says "undefined is not an object (evaluating 'e.props.navigation.navigate').
Can someone help me please
Try changing this:
navigationOptions: {
headerRight: <BurgerMenu /> ,
title: "Header"
},
by this:
navigationOptions: ({navigation}) => ({
headerRight: <BurgerMenu navigation={navigation} />,
title: "Header"
}),
Also you can refer to this example on my github.