React-Navigation: aligning header to center - javascript

I am having trouble aligning my custom header to the middle of the header in a Stack Navigation.
This is my current view:
I would like to have the menu icon to the left and the title centered.
My current code for the screenOptions in the StackNavigator are
headerStyle: {
backgroundColor: "#a5ade8",
height: 80
},
headerTintColor: "#383f42",
headerTitleStyle: {
fontFamily: "heebo-black",
fontSize: 24
}
My code in my custom header is:
return (
<View style={styles.container}>
<MaterialIcons
name="menu"
style={styles.icon}
size={24}
onPress={openDrawer}
/>
<View>
<Text style={styles.headerTitle}>{title}</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex:1,
height: "100%",
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
},
headerTitle: {
fontFamily: "heebo-black",
fontSize: 24,
color: "#383f42",
letterSpacing: 1,
},
icon: {
position: "absolute",
left: 16
}
});
I have set my width to 100% in my header, however it takes only takes the space of the text...
Any help would be greatly appreciated!

Have you tried to use the headerTitleAlign option in screenOptions?
const HomeStackNavigator = () => {
return (
<Stack.Navigator
initialRouteName="Reviews"
screenOptions={{
headerTitleAlign: "center"
}}
>
<Stack.Screen
name="Reviews"
component={Home}
options={{
headerTitle: () => (
<View style={styles.container}>
<View>
<Text style={styles.headerTitle}>Reviews App</Text>
</View>
</View>
),
headerLeft: () => (
<MaterialIcons name="menu" size={35} style={styles.icon} />
)
}}
/>
</Stack.Navigator>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
height: "100%",
flexDirection: "row",
alignItems: "center"
},
headerTitle: {
fontSize: 24,
color: "#383f42",
letterSpacing: 1
},
icon: {
marginLeft: 10
}
});

try
textAlign:'center'
at the header title styles

Can you see the example here in this expo-snack , there in place of icon ive used text and your header is aligned center.
Hope it helps. feel free for doubts

Related

Absolute positioning causes React Native component to go off screen

One of my React Native screens needs to have a TouchableOpacity at the bottom of the screen. I've tried setting position: "absolute" and bottom: 0, however, this just causes the element to be a few hundred pixels below the screen. How can I make my TouchableOpacity be at the bottom of the screen all the time?
<View style={styles.mainView}>
<View style={{ position: "relative" }}>
<TouchableOpacity style={styles.cartView}>
<Text style={styles.cartText}>View cart</Text>
</ViewTouchableOpacity
</View>
}
/>
</View>
//styles
const styles = StyleSheet.create({
mainView: {
// devDims are the device dimensions
minHeight: devDims.height,
minWidth: devDims.width,
backgroundColor: "white",
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
},
cartView: {
justifyContent: "center",
alignItems: "center",
maxHeight: 50,
minWidth: "100%",
alignSelf: "center",
marginTop: 50,
padding: 10,
borderRadius: 20,
},
cartText: {
fontFamily: "semi",
fontSize: 22,
},
});
We could handle this without absolute positioning using flex alone.
Add flex:1 to the parent view and to the view that wraps the sticky bottom. Then, add flex: 2 to the view that wraps the other content.
Here is a minimal generic component that lets you add a sticky bottom component.
const MainScreen = ({bottom, children}) => {
return <View style={{flex: 1, backgroundColor: 'red'}}>
<View style={{flex: 2, backgroundColor: 'green'}}>
{children}
</View>
<View style={{flex: 1, backgroundColor: 'yellow'}}>
{bottom}
</View>
</View>
}
export default function App() {
return <MainScreen bottom={
<TouchableOpacity style={styles.cartView}>
<Text style={styles.cartText}>View cart</Text>
</TouchableOpacity>}>
</MainScreen>
}
The result looks as follows:
However, we can use absolute positioning as well. You are just missing the flex: 1 for the parent view.
export default function App() {
return <View style={styles.mainView}>
<View style={{ position: "absolute", bottom: 0 }}>
<TouchableOpacity style={styles.cartView}>
<Text style={styles.cartText}>View cart</Text>
</TouchableOpacity>
</View>
</View>
}
const styles = StyleSheet.create({
mainView: {
flex: 1,
// devDims are the device dimensions
minHeight: devDims.height,
minWidth: devDims.width,
backgroundColor: "red",
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
},
cartView: {
justifyContent: "center",
alignItems: "center",
maxHeight: 50,
minWidth: "100%",
backgroundColor: "yellow",
alignSelf: "center",
marginTop: 50,
padding: 10,
borderRadius: 20,
},
cartText: {
fontFamily: "semi",
fontSize: 22,
},
});
The result is as follows:
if you are using position as absolute then your view must be last view before last closed view tag
When you have declared any view at bottom of the screen then you should be do like this
import {View, SafeAreaView} from 'react-native';
<SafeAreaView style={{flex:1}}>
<View style={{flex:1}}>
<!---Anything extra views---!>
<View style={{bottom:0,position:'absolute',start:0,end:0}}> !-- you're bottom view
<TouchableOpacity style={styles.cartView}>
<Text style={styles.cartText}>View cart</Text>
</ViewTouchableOpacity
</View>
</View>
</SafeAreaView >

horizontal ScrollView is not scrolling

When adding horizontal={true} to my scrollview, I thought that would be enough to be able to scroll sideways. For some reason, even though there is enough content to scroll to, the images will not scroll continuously. If you copy and paste this code into snack.expo.io you will see what I mean.
I am not sure what is causing this issue, as I know the normal scrollview vertically works fine and scrolls like normal. I have also tried using nestedScrollenabled to true
Any insight at all is appreciated more than you know!
import React, { useState } from 'react';
import {Pressable, StyleSheet, Text, View, useWindowDimensions, Dimensions, Image, Animated, PanResponder,
TouchableOpacity, ScrollView, ImageBackground, Platform} from 'react-native';
import { SearchBar } from 'react-native-elements';
import {
scale,
verticalScale,
moderateScale,
ScaledSheet,
} from 'react-native-size-matters';
import { MaterialCommunityIcons } from '#expo/vector-icons';
const Images = [
{ id: '1', uri: require('./assets/snack-icon.png'), text: 'Test' },
{ id: '2', uri: require('./assets/snack-icon.png') /*text: "Test"*/ },
{ id: '3', uri: require('./assets/snack-icon.png') /*text: "Test"*/ },
{ id: '4', uri: require('./assets/snack-icon.png') /*text: "Test"*/ },
]
const pressableTest = () => {
let textlog = '';
const [state, setState] = useState(0);
};
export default class Home extends React.Component {
renderImagesHorizontal = () => {
return Images.map((item, i) => {
return (
<View
style={{
width : '150%',
paddingLeft: scale(10),
paddingRight: scale(10),
paddingBottom: scale(15),
}}>
<TouchableOpacity
onPress={() => this.props.navigation.navigate('VenueDetails')}>
<ImageBackground
source={item.uri}
style={{
width: '100%',
height: scale(225),
shadowColor: '#000',
shadowOffset: { width: 1, height: 4 },
shadowOpacity: 1,
}}
imageStyle={{ borderRadius: 10 }}>
<View
style={{
position: 'absolute',
bottom: 10,
left: 10,
justifyContent: 'flex-start',
alignItems: 'flex-start',
}}>
<Text style={styles.name}>Name</Text>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Text style={styles.category}>Category</Text>
<Text style={styles.dot}>⬤</Text>
<Text style={styles.money}>$$</Text>
<Text style={styles.dot}>⬤</Text>
<Text style={styles.starRating}>★★★</Text>
</View>
</View>
</ImageBackground>
</TouchableOpacity>
</View>
);
});
};
renderImagesVertical = () => {
return Images.map((item, i) => {
return (
<View style={{ paddingLeft: scale(10), paddingRight: scale(10), paddingBottom: scale(20) }}>
<TouchableOpacity
onPress={() => this.props.navigation.navigate('VenueDetails')}>
<ImageBackground
source={item.uri}
style={{ width:'100%', height: scale(125),
shadowColor: '#000',
shadowOffset: {width: 1, height: 7},
shadowOpacity: 1,}} imageStyle = {{ borderRadius: 20}}>
<View
style={{
position: 'absolute',
bottom: 10,
left: 10,
justifyContent: 'flex-start',
alignItems: 'flex-start',
}}>
<Text style={styles.name}>Name</Text>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Text style={styles.category}>Category</Text>
<Text style={styles.dot}>⬤</Text>
<Text style={styles.money}>$$</Text>
<Text style={styles.dot}>⬤</Text>
<Text style={styles.starRating}>★★★</Text>
</View>
</View>
</ImageBackground>
</TouchableOpacity>
</View>
);
});
};
state = {
search: '',
};
updateSearch = (search) => {
this.setState({ search });
};
render() {
const { search } = this.state;
return (
<ScrollView style={{ flex: 1, backgroundColor: '#272933', horizontal: 'true' }}>
<View style={{flexDirection:'row', marginTop: scale(20)}}>
{/*this will proabbly say somethign different and probably have a different look to it but you get the idea
I was also trying to add a shadow to this but couldnt figure it out. */}
<Text style={{marginTop: scale(30) ,fontSize: scale(40), fontWeight: 'bold', color: '#FFFFFF', paddingLeft: scale(20)}}>
Home
</Text>
<View style={{paddingTop: scale(40), paddingLeft: scale(155)}}>
</View>
</View>
<SearchBar
placeholder="Search..."
onChangeText={this.updateSearch}
value={search}
round='true'
containerStyle={{backgroundColor: '#272933', borderBottomColor: 'transparent', borderTopColor: 'transparent',
paddingLeft: scale(20) , paddingRight: scale(20)}}
inputContainerStyle={{height: scale(30), width: scale(310), backgroundColor: '#3A3B3C'}}
searchIcon={() => <MaterialCommunityIcons name="glass-mug-variant" size={25} color='#87909A'/>}
clearIcon= 'null'
/>
<ScrollView
horizontal={true}
>
<View style={{ flex: 1, flexDirection : 'row', marginTop: 15 }}>{this.renderImagesHorizontal()}</View>
</ScrollView>
<View style={{ flex: 1, marginTop: 15 }}>{this.renderImagesVertical()}</View>
</ScrollView>
);
}
}
const styles = ScaledSheet.create({
starRating: {
color: 'white',
fontSize: '20#s',
textShadowOffset: { width: 2, height: 2 },
textShadowRadius: 2,
textShadowColor: '#000',
},
category: {
color: 'white',
fontSize: '20#s',
textShadowOffset: { width: 2, height: 2 },
textShadowRadius: 2,
textShadowColor: '#000',
},
name: {
fontWeight: 'bold',
color: 'white',
fontSize: '25#s',
textShadowOffset: { width: 2, height: 2 },
textShadowRadius: 2,
textShadowColor: '#000',
},
dot: {
color: 'white',
fontSize: '5#s',
paddingLeft: '5#s',
paddingRight: '5#s',
textShadowOffset: { width: 2, height: 2 },
textShadowRadius: 2,
textShadowColor: '#000',
},
money: {
color: 'white',
fontSize: '20#s',
},
});
in android you must add nestedScrollEnabled={true} to Enables nested scrolling for Android API level 21+. see here
<ScrollView>
<ScrollView nestedScrollEnabled={true}>
</ScrollView>
</ScrollView>
try snack here (test in android & ios not web)

How do I fix my navigation in React Native?

I'm simply trying to make the buttons in my homeScreen navigate to other screens when pressed so I used react-navigation to make a navigation stack to handle this. However, I'm getting this error whenever I try to navigate to another screen by pressing the appropriate buttons: "The action 'NAVIGATE' with payload {"name":"Client Connect"} was not handled by any navigator.
Do you have a screen named 'Client Connect'?
If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator."
I'm not sure how to fix this how so I would really appreciate some help with this. Thank you
homeScreen(Screen with buttons that should navigate to other pages):
import React from 'react';
import {View, FlatList, Text, TouchableOpacity, Dimensions} from 'react-native';
import LinearGradientScreen from './linearGradientScreen';
import Feather from 'react-native-vector-icons/Feather';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Entypo from 'react-native-vector-icons/Entypo';
const CellComponent = (props) => {
return (
<TouchableOpacity
onPress={() => props.navigation.navigate(props.item.name)}
style={{
backgroundColor: props.item.color,
height: (13 * Dimensions.get('window').height) / 100,
width: 132,
borderRadius: 5,
shadowColor: 'rgba(52,2,2,1)',
shadowOffset: {
width: 3,
height: 3,
},
elevation: 5,
shadowOpacity: 1,
shadowRadius: 0,
margin: 20,
alignItems: 'center',
justifyContent: 'center',
}}>
{props.item.family === 'Feather' ? (
<Feather
type={props.item.type}
color={'rgba(255,255,255,1)'}
name={props.item.icon}
size={30}
/>
) : null}
{props.item.family === 'MaterialCommunityIcons1' ? (
<MaterialCommunityIcons
type={props.item.type}
color={'rgba(255,255,255,1)'}
name={props.item.icon}
size={30}
/>
) : null}
{props.item.family === 'Entypo' ? (
<Entypo
type={props.item.type}
color={'rgba(255,255,255,1)'}
name={props.item.icon}
size={30}
/>
) : null}
{props.item.family === 'MaterialCommunityIcons2' ? (
<MaterialCommunityIcons
type={props.item.type}
color={'rgba(255,255,255,1)'}
name={props.item.icon}
size={30}
/>
) : null}
{props.item.family === 'MaterialCommunityIcons' ? (
<MaterialCommunityIcons
type={props.item.type}
color={'rgba(255,255,255,1)'}
name={props.item.icon}
size={30}
/>
) : null}
{props.item.family === 'FontAwesome' ? (
<FontAwesome
type={props.item.type}
color={'rgba(255,255,255,1)'}
name={props.item.icon}
size={30}
/>
) : null}
<Text
style={{
color: 'white',
fontSize: 18 * Dimensions.get('window').fontScale,
}}>
{props.item.name}
</Text>
</TouchableOpacity>
);
};
const HomeScreen = (props) => {
return (
<LinearGradientScreen>
<View style={{alignItems: 'center', justifyContent: 'center'}}>
<Text
style={{
marginTop: '20%',
fontSize: 50 * Dimensions.get('window').fontScale,
color: 'white',
fontWeight: 'bold',
}}>
Home
</Text>
<Text
style={{
fontSize: 25 * Dimensions.get('window').fontScale,
color: 'white',
fontWeight: '400',
marginBottom: '10%',
}}>
Select a service
</Text>
<FlatList
numColumns={2}
data={HomeScreenData}
renderItem={({item}) => {
return <CellComponent {...props} item={item} />;
}}
/>
</View>
</LinearGradientScreen>
);
};
const HomeScreenData = [
{
id: 1,
name: 'AI Chat',
icon: 'cpu',
family: 'Feather',
routeName: 'AiScreen',
color: 'rgba(247,52,122,1)',
},
{
id: 2,
name: 'Live Chat',
icon: 'wechat',
family: 'FontAwesome',
color: 'rgba(16,165,245,1)',
},
{
id: 3,
name: 'Resources',
icon: 'file-document-outline',
family: 'MaterialCommunityIcons',
color: 'rgba(74,74,74,1)',
},
{
id: 1,
name: 'Client Connect',
icon: 'gesture-swipe-horizontal',
family: 'MaterialCommunityIcons1',
color: 'rgba(237,41,57,1)',
},
{
id: 1,
name: 'DM',
icon: 'message',
family: 'Entypo',
color: 'rgba(74,144,226,1)',
},
{
id: 1,
name: 'Profile',
icon: 'tooltip-account',
family: 'MaterialCommunityIcons2',
color: 'rgba(144,19,254,1)',
},
];
export default HomeScreen;
Navigation Stack:
import * as React from 'react';
import { Button, View, Text, FlatList } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import HomeScreen from './HomeScreen';
import AiScreen from './AiScreen';
function AiChatScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Ai AiChatScreen</Text>
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="AI Chat" component={AiScreen} />
<Stack.Screen name="Resources" component={ResourcesScreen} />
<Stack.Screen name="DM" component={DmScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Live Chat" component={LiveChatScreen} />
<Stack.Screen name="Client Connect" component={ClientConnectScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
function LiveChatScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Live Chat Screen</Text>
</View>
);
}
function ResourcesScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Resources Screen</Text>
</View>
);
}
function ClientConnectScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Client Connect Screen</Text>
</View>
);
}
function DmScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>DM Screen</Text>
</View>
);
}
function ProfileScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Profile Screen</Text>
</View>
);
}
export default App;

How to position Icon on right side of text

I tried many ways but unfortunately it still doesn't work please help me out!
I've tried reversing the Text and Icon but still doesn't work
Here is the class
export class More extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.list}>
<View style={styles.hairline}>
<Text style={styles.text}>
<Text>أضف إعلانك</Text>
<Icon name="ios-add" size={20}/>
</Text>
</View>
<View style={styles.hairline}>
<Text style={styles.text}><Icon name="ios-heart" size={20}/> إعلانات المفضلة</Text>
</View>
</View>
</View>
);
}
}
Here is the StyleSheet
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
},
list: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'flext-start',
},
text: {
padding: 10,
textAlign: 'right',
alignSelf: 'stretch',
},
icon: {
flexDirection: 'row',
alignItems: 'flex-end'
},
hairline: {
borderBottomColor: '#A2A2A2',
borderBottomWidth: 1,
},
});
I want the Icon to show up on the right side of the text not the left side.
Try this:
const TextWithIcon = ({ text, iconName }) => (
<View
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
}}
>
<View style={{ marginRight: 8 }}>
<Text>{text}</Text>
</View>
<Icon name={iconName} size={20} />
</View>
);

flex:1 not filling whole screen

I'm trying to change the background color of my app, but the color doesn't fill the whole screen. When I set flex to 0, the background color only spans the needed amount, but when I set it to 1, instead of expanding the whole screen, it shrinks. What did I do wrong?
Here's the code, changing the root view flex:
render() {
return (
<Text>{welcome}</Text>
<TextInput
underlineColorAndroid="rgba(0,0,0,0)"
placeholder={email}
autoCapitalize="none"
style={styles.textInput}
onChangeText={email1 => this.setState({ email1 })}
/>
<TextInput
underlineColorAndroid="rgba(0,0,0,0)"
secureTextEntry
placeholder={password}
autoCapitalize="none"
style={styles.textInput}
onChangeText={password1 => this.setState({ password1 })}
value={this.state.password1}
/>
{this.state.errorMessage && (
<Text style={styles.error}>{this.state.errorMessage}</Text>
)}
<TouchableOpacity
onPress={this.handleSignUp}
style={styles.buttonContainer}
>
<Text style={styles.buttonText}>{signup}</Text>
</TouchableOpacity>
<Text
style={styles.text}
onPress={() => this.props.navigation.navigate("LoginScreen")}
>
{already_have_an_account}
</Text>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
justifyContent: "center",
padding: 20,
backgroundColor: "red",
flex: 0
},
textInput: {
height: 40,
marginTop: 8,
paddingHorizontal: 8,
backgroundColor: "#e2e2e2"
},
buttonContainer: {
backgroundColor: "#3bd774",
padding: 15,
marginTop: 10
},
buttonText: {
textAlign: "center",
color: "white",
fontWeight: "bold"
},
logo: {
width: 200,
height: 200
},
logoContainer: {
alignItems: "center",
justifyContent: "center"
},
text: {
marginTop: 16,
color: "#bcbcbc",
textAlign: "center"
},
error: {
marginTop: 8,
color: "red"
}
});
You need to make sure you have flex:1 all the way down the chain of views. This is because flex: 1 will make the view fill its parent
I can see that what you have copy/pasted isn't all of the code, since there is a </KeyboardAvoidingView> but no opening tag.
So, at the very least you need a <KeyboardAvoidingView style={{flex: 1}}>, but if there is something wrapping that, you should add flex:1 to that control as well.
Put whole layout in a View wrapper and give this style to this view
container: {
justifyContent: "center",
padding: 20,
alignItems:'center',
backgroundColor: "red",
flex: 1
}
Running example: https://snack.expo.io/Hy-Gv-lGm

Categories