How to fix react navigation displacing my component from top of screen? - react-native

I am working on a react native application and am trying to understand how to deal with react navigation as it affects my styling. Essentially when I navigate to a page, react navigation's top arrow with header is displacing my components (I'd like to move my black header bar up and use react navigation's arrow ideally):
I have react navigation set up in the following manner:
App.js
const ProfileNavigator = createStackNavigator({
//Profile: { screen: Profile},
QR: { screen: GenerateQR },
EditAccount: { screen: EditAccount }
});
const AppNavigator = createSwitchNavigator({
tabs: bottomTabNavigator,
profile: ProfileNavigator
})
const AppContainer = createAppContainer(AppNavigator);
I have a header component I put together for styling that I use on top of each page:
pageTemplate
import React, {Component} from 'react';
import {Text,View, StyleSheet} from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { Ionicons } from '#expo/vector-icons';
class PageTemplate extends Component {
render() {
return (
<View
style={{
flexDirection: 'row',
height: 130,
alignSelf: 'stretch',
width: '100%'
}}>
<View style={{backgroundColor: 'black', alignSelf: 'stretch',width: '100%'}} />
<View style=
{{position:'absolute',
marginTop: '16%',
marginLeft: '3%',
display: 'flex',
flexDirection: 'row',
flex:1
}}>
<TouchableOpacity onPress={this.props.navigate}>
<Ionicons name="ios-arrow-dropleft" size={32} color="white" />
</TouchableOpacity>
</View>
<Text
style={{
position: 'absolute',
marginTop: '15%',
marginLeft: '12%',
color: 'white',
fontSize: 30}}
>
{this.props.title}
</Text>
</View>
);
}
}
export default PageTemplate;
I have a tab called profile which navigates through a list item to get to an account edits page:
Profile
import React from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, TouchableHighlight } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import { List, ListItem } from 'react-native-elements'
import GenerateQR from './generateQR';
import PageTemplate from './smallComponents/pageTemplate';
import pic from '../assets/bigRate.png'
export default class Profile extends React.Component {
render() {
const { navigate } = this.props.navigation;
navigateBack=()=>{
navigate('Queue')
}
return(
<React.Fragment>
<PageTemplate title={'Profile Settings'} navigate={navigateBack} />
{/*<Image source={pic} />*/}
{/** Frst Section */}
<View style={{
//backgroundColor:'blue'
}}>
<Text style={styles.section}>Account Information</Text>
</View>
<TouchableOpacity
onPress={()=>{navigate('EditAccount')}}
style={{position: 'absolute',
marginTop:'32%',
flex:1,
flexDirection: 'row',
flexWrap: 'wrap'}}>
<View style={{
marginLeft:'5%',
flex:1,
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'flex-start',
//backgroundColor:'yellow',
alignItems: 'center',
//borderRadius:50,
//height:'60%'
}} >
<Ionicons style={{marginLeft:'20%'}} name="ios-person" size={72} />
</View>
<View style={{paddingTop:50,
marginRight:'40%',
flex:2,
flexDirection: 'row',
flexWrap: 'wrap',
//backgroundColor: 'red'
}}
>
<Text>Sylvester Stallone</Text>
<Text>+1 646-897-0098</Text>
<Text>SlyLone#gmail.com</Text>
</View>
</TouchableOpacity>
{/**add line section */}
</React.Fragment>
);
}
}
const styles = StyleSheet.create({
option : {
//position: 'absolute',
marginLeft:'7%',
alignSelf: 'stretch',
width: '100%',
height: '15%',
//flexWrap: 'wrap',
justifyContent:'space-between',
//padding:20
},
section : {
fontSize:20,
marginLeft:'5%'
}
})
/**
*
*
*
<View style={styles.option}>
<Ionicons name="ios-gift" size={32} />
<TouchableHighlight>
<Text>Rewards</Text>
</TouchableHighlight>
</View>
*
*/
Ideally it be nice to drop the arrow icon and move the header up keeping react-navigations arrow.

If you want to get rid of the arrows, you can create your own headers.
Example
class LogoTitle extends React.Component {
render() {
return (
<Image
source={require('#expo/snack-static/react-native-logo.png')}
style={{ width: 30, height: 30, alignSelf:"center" }}
/>
);
}
}
class HomeScreen extends React.Component {
static navigationOptions = {
// headerTitle instead of title
headerTitle: () => <LogoTitle />,
headerLeft: () => (
<Button
onPress={() => alert('This is a button!')}
title="back"
color="#fff"
/>
),
};

Related

getting white space at top when using react-native navigation

I am using react navigation to navigate between different screens.
below is my code:
import React from 'react';
import { StyleSheet, Text, View, Button, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Home from "./screen/Home";
function Main({ navigation }) {
return (
<View style={styles.container}>
<View style={{flex: 0}}>
<Text>Welcome</Text>
</View>
<View style={{flex: 0}}>
<TouchableOpacity style={styles.btn} onPress={() => navigation.navigate('Home')}>
<Text>Goto Home</Text>
</TouchableOpacity>
</View>
</View>
);
}
const MainNavigator = createStackNavigator();
export default class App extends React.Component {
render() {
return (
<NavigationContainer>
<MainNavigator.Navigator >
<MainNavigator.Screen name="Main" component={Main} />
<MainNavigator.Screen name="Home" component={Home} />
</MainNavigator.Navigator>
</NavigationContainer>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1, backgroundColor: '#44210D', alignItems: 'center', justifyContent: 'center',
},
text: {
color: "black", borderWidth: 2, borderColor: "green"
},
btn: {
alignItems: "center", backgroundColor: "#DDDDDD", padding: 10,margin: 10
},
});
You can see in the image that there is a white space at the top. I want to know how can I change the color of that space.

How to navigate to other page after click on button in react native?

I am an beginner in react native.I want to display home page after logged in.I have install react-navigator using npm install and I have tried below code.
But I am getting below error, I tried to solve this. Still I have the error.
In App.js
//This is an example code for Bottom Navigation//
import React, { Component } from 'react';
//import react in our code.
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native';
//import all the basic component we have used
import { createStackNavigator, createAppContainer } from 'react-navigation';
export default class App extends Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ marginTop: 50, fontSize: 25 }}>Setting!</Text>
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Go to Home Tab</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Open Detail Screen</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Open Profile Screen</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
width: 300,
marginTop: 16,
},
});
Can anyone assist me to solve this?
You can do it as following:
import React from "react";
import { View, Text } from "react-native";
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
class LoginScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Login Screen</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
</View>
);
}
}
on App.js,
import React from 'react';
import { HomeScreen, LoginScreen } from '..'// should set the proper path.
const AppNavigator = createStackNavigator({
Login: LoginScreen,
Home: HomeScreen
});
const App = () => {
return <AppNavigator />;
}
export default App;

navigate.dispatch(DrawerActions.closeDrawer()) not working in React Native

On click of a cross button the drawer should be closed, that is the
thing I am trying. I have passed down the props inside component but
giving error that navigate.dispatch(DrawerActions.closeDrawer()) is
undefined.
I am providing My code
SideMenu.js which the layout of drawer menu. From here I am passing
props to drawerheader.
import React, {Component} from 'react';
import { View, StyleSheet} from 'react-native';
import DrawerHeader from './DrawerHeader';
import DrawerMenu from './DrawerMenu';
import { StackNavigator } from 'react-navigation';
class SideMenuLayout extends Component {
state = {
menuNames:[{
id:'0',
name:'My Profile',
link:''
},{
id:'1',
name:'Place Order',
link:''
},{
id:'2',
name:'Order History',
link:'OrderHistory'
},{
id:'3',
name:'Payment',
link:''
},{
id:'4',
name:'Recharge',
link:''
},{
id:'5',
name:'Help',
link:''
},{
id:'6',
name:'Logout',
link:''
}]
}
render () {
return (
<View style={styles.container} >
<DrawerHeader navigation={this.props.navigation}/>
<DrawerMenu
navigation={this.props.navigation}
menuItems={this.state}
style={{ marginTop: 106/3}}
/>
</View>
);
}
}
export default SideMenuLayout;
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor: "#ffffff",
}
});
Drawer Header code goes here. Here I am trying to close the navigation drawer.
import React, {Component} from 'react';
import {Text, View, StyleSheet,Image,TouchableOpacity} from 'react-native';
import { FontAwesome } from '#expo/vector-icons';
import { DrawerActions, StackNavigator } from 'react-navigation';
const DrawerHeader = (props)=> {
const { navigate } = props.navigation;
return (
<View style={{backgroundColor: '#d61822',width:DRAWER_CONTAINER_WIDTH/3,height:DRAWER_CONTAINER_HEIGHT/3 }}>
<View style={styles.titleContainer}>
<View style={{ marginLeft:20, backgroundColor:'#d61822',height:40 }}>
<Text style={{fontSize:28,fontStyle:'italic',color:'#ffff',fontWeight:'bold'}}>
Prabhuji Online
</Text>
</View>
<View style={{ marginLeft:35,backgroundColor:'#d61822',width: 50, height: 40,paddingRight:10,alignItems:'center',justifyContent:'center' }}>
<TouchableOpacity onPress={()=>navigate.dispatch(DrawerActions.closeDrawer())}>
<Text style={{fontSize:20,color:'#ffff',}}>
<FontAwesome
style={{ alignSelf: 'flex-end'}}
name="times"
size={18}
color="#ffffff"
/>
</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.fakeContainer}>
</View>
<View style={{
position:'absolute',
top: 170/3,
marginLeft:20,
width:220/3,
height:220/3,
backgroundColor:'#fffcf9',
borderRadius:(220/3)/2,
justifyContent:'center',
alignContent:'center',
alignItems:'center',
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 5,
},
shadowOpacity: 0.25,
shadowRadius: 6.27,
elevation: 7,
}}>
<Image
tintColor='red'
style={{
width: 111/3,
height: 111/3,
}}
source={require('../../../assets/place_order.png')}/>
</View>
</View>
);
}
export default DrawerHeader;
const styles = StyleSheet.create({
titleContainer:{
backgroundColor: '#d61822',
flexDirection: 'row',
height:TITLE_CONTAINER_HEIGHT/3,
marginTop: 50/3,
},
fakeContainer:{
position:'relative',
height:FAKE_CONTAINER_HEIGHT/3,
backgroundColor: '#ffffff',
//backgroundColor: 'yellow',
}
});
Can any one please tell me what is going wrong here?
I have also tried navigate.closeDrawer(). But same error is giving.
Instead of using the navigate call, you need to dispatch the action like this: this.props.navigation.dispatch(*your action here*), as described in the docs: https://reactnavigation.org/docs/en/navigation-prop.html#dispatch-send-an-action-to-the-router

React native align icon and text

for the love of God, every styling i put on the stylesheet doesn't change anything.
i tried style the view, sectionheader & sectionbox but no luck
i want to align 4 icons in the boxsection and text below then as such, please any help would be appreciated.
export default class HomePage extends Component {
render() {
return (
<View>
<SectionHeader title={'Food'} />
<View >
<SectionBox >
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Text style={styles.sectiontext}>burgers</Text>
</SectionBox>
</View>
const styles = StyleSheet.create({
icons: {
flexDirection: 'row',
paddingTop: 7,
paddingLeft: 5,
},
sectiontext: {
fontSize: 15,
fontWeight: 'bold',
paddingLeft: 5,
alignItems: 'center',
}
});
For the icons-containing-box you would need to indicate flexDirection and flexWrap, not directly on the icon's style. Then to get the text below each icon you need to wrap icon and text in its own view and give that 'column' direction.
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import { Constants } from 'expo';
const ICON_SIZE = 70;
const FONT_SIZE = 18;
const getItem = () => (
<View style={styles.iconStyle}>
<Ionicons name="md-checkmark-circle" size={ICON_SIZE} color="green" />
<Text style={styles.textStyle}>name</Text>
</View>
);
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.iconContainer}>
{getItem()}
{getItem()}
{getItem()}
{getItem()}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
iconContainer: {
width: ICON_SIZE * 2,
flexDirection: 'row',
flexWrap: 'wrap',
},
iconStyle: {
flexDirection: 'column',
alignItems: 'center',
padding: 5,
},
textStyle: {
fontSize: FONT_SIZE,
},
});
You need a view for each group of icon and text with a flexDirection: 'column' and one another view for each row (or column), like the example below:
https://snack.expo.io/HJY7IWsFm
Other option is to use a GridView lib:
https://github.com/saleel/react-native-super-grid

Customizing default navigation bar of react-native-router-flux

I am using react native router flux for navigation in my react native project. Router flux has a default navBar.
Is there a way to customize the navBar? like, changing colour of text and background.
I tried editing the file in node_modules/react-native-router-flux/src/navBar.js but it doesn't seem to work.
Please help me.
In your Router.js file where you create your scenes give a navBar property like for eg:
navBar={NavBar} and here my NavBar is actually a NavBar.js file in which I have customized the navigation bar
just have a look on my codes if that helps u
Router.js file:
import React from 'react';
import { Scene, Router } from 'react-native-router-flux';
import mainScreen from './components/mainScreen';
import challengeScreen from './components/challengeScreen';
import NavBar from './components/NavBar';
const RouterComponent = () => {
return (
<Router>
<Scene key="root">
<Scene key="homeScreen" component={mainScreen} hideNavBar={1} />
<Scene
key="screen2" component={challengeScreen} navTransparent={1}
navBar={NavBar}
/>
</Scene>
</Router>
);
};
export default RouterComponent;
NavBar.js file
import {
View, Image, StatusBar, TouchableWithoutFeedback
} from 'react-native';
import React, { Component } from 'react';
import { Actions, Router, Scene } from 'react-native-router-flux';
class NavBar extends Component {
render() {
return (
<View style={styles.backgroundStyle}>
<StatusBar />
<View style={{ flexDirection: 'row' }}>
<TouchableWithoutFeedback onPress={() => Actions.homeScreen()}>
<Image
source={require('./Images/back-arrow.png')}
style={styles.backarrowStyle} />
</TouchableWithoutFeedback>
<Image
source={require('./Images/help.png')}
style={styles.helpStyle} />
<Image
source={require('./Images/setting.png')}
style={styles.settingStyle} />
</View>
</View>
);
}
}
const styles = {
backgroundStyle: {
backgroundColor: 'transparent'
},
backarrowStyle: {
resizeMode: 'contain',
flexDirection: 'row',
width: 50,
height: 50,
left: 0,
justifyContent: 'flex-start'
},
helpStyle: {
resizeMode: 'contain',
width: 50,
height: 50,
left: 220,
justifyContent: 'flex-end',
position: 'relative'
},
settingStyle: {
resizeMode: 'contain',
width: 50,
height: 50,
justifyContent: 'flex-end',
position: 'relative',
left: 210
}
};
export default NavBar;
This helped me to customize navigation bar
hope that it helps you
You should add navigationBarStyle property for customizing navigation bar.You can review following code:
<Scene key="key1" icon={TabIcon} title="book-open">
<Scene key="key2" hideNavBar={false}
navigationBarStyle={{backgroundColor:'transparent',marginTop:8, borderBottomWidth:0}}
component={TestComponent}
title=""/>
</Scene>
Also this subject is mentioned in here.https://github.com/aksonov/react-native-router-flux/issues/160
There is a working example in the examples folder of the react-native-router-flux repository.
For instance, your custom navbar would be:
import { Image, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import React from 'react';
import { Actions } from 'react-native-router-flux';
const styles = StyleSheet.create({
container: {
height: Platform.OS === 'ios' ? 64 : 54,
flexDirection: 'row',
paddingTop: 20,
},
navBarItem: {
flex: 1,
justifyContent: 'center',
},
});
export default class CustomNavBar extends React.Component {
// constructor(props) {
// super(props)
// }
_renderLeft() {
if (Actions.currentScene === 'customNavBar1') {
return (
<TouchableOpacity onPress={() => console.log('Hamburger button pressed')} style={[styles.navBarItem, { paddingLeft: 10 }]}>
<Image
style={{ width: 30, height: 50 }}
resizeMode="contain"
source={{ uri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Hamburger_icon.svg/1200px-Hamburger_icon.svg.png' }}
/>
</TouchableOpacity>
);
}
return (
<TouchableOpacity onPress={Actions.pop} style={[styles.navBarItem, { paddingLeft: 10 }]}>
<Image style={{ width: 30, height: 50 }} resizeMode="contain" source={{ uri: 'https://image.flaticon.com/icons/png/512/0/340.png' }} />
</TouchableOpacity>
);
}
_renderMiddle() {
return (
<View style={styles.navBarItem}>
<Text>{this.props.title}</Text>
</View>
);
}
_renderRight() {
return (
<View style={[styles.navBarItem, { flexDirection: 'row', justifyContent: 'flex-end' }]}>
<TouchableOpacity onPress={() => console.log('Share')} style={{ paddingRight: 10 }}>
<Image style={{ width: 30, height: 50 }} resizeMode="contain" source={{ uri: 'https://cdn3.iconfinder.com/data/icons/glypho-free/64/share-512.png' }} />
</TouchableOpacity>
<TouchableOpacity onPress={() => console.log('Search')} style={{ paddingRight: 10 }}>
<Image style={{ width: 30, height: 50 }} resizeMode="contain" source={{ uri: 'https://maxcdn.icons8.com/Share/icon/p1em/Very_Basic//search1600.png' }} />
</TouchableOpacity>
</View>
);
}
render() {
let dinamicStyle = {};
if (Actions.currentScene === 'customNavBar1') {
dinamicStyle = { backgroundColor: 'red' };
} else {
dinamicStyle = { backgroundColor: 'yellow' };
}
return (
<View style={[styles.container, dinamicStyle]}>
{this._renderLeft()}
{this._renderMiddle()}
{this._renderRight()}
</View>
);
}
}
It works perfectly for me. Just don't forget to set the navBar property of your Scene or Stack:
<Scene navBar={CustomNavBar} key='myKey' component={MyComponent} />
react-native-router-flux provide some api to do this, take a look at https://github.com/aksonov/react-native-router-flux/blob/master/docs/API_CONFIGURATION.md, maybe titleStyle and navigationBarStyle are what you need.