Align back button in the left and text in the center - react-native

I want to put the string 'example' in the middle of the header.
Code:
<View style={viewStyle}>
<ImageButton
imageUrl={require('./assets/icons/Back-25.png')}
onPress={props.onPressPhone}
/>
<Text>{props.headerText}</Text>
</View>
viewStyle:
backgroundColor: 'white',
alignItems: 'center',
height: 60,
paddingTop: 15,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.2,
elevation: 2,
position: 'relative',
flexDirection: 'row',
justifyContent: 'space-between',
Image Button style:
alignSelf: 'center',

One way to do this is to use a same-size empty .png image on the other side, and space-between in your header styling:
<View style={ styles.header }>
<Button style={{left: 10}} onPress={ () => this.handlePress() }>
<Image source={ require('../images/arrow_back.png') } style={{ width: 50, height: 50 }} />
</Button>
<Text style={styles.header_text} >{this.props.title}</Text>
<Button style={{right: 10}}>
<Image source={ require('../images/no_image.png') } style={{ width: 50, height: 50 }} />
</Button>
</View>
and
header: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: width,
backgroundColor: '#09146d',
},
...a bit kludgy, but it has worked for me. Alternatively, you could divide up the header with flex-based views, using flexDirection: 'row' :
<View style={ styles.header }>
<View style={{flex: 1}}>
//Button in here
</View>
<View style={{alignItems: 'center', flex: 6}}>
//Text in here
</View>
<View style={{flex: 1}}>
//Nothing in here
</View>
</View>
Good luck!

Expand on kwishnu's flex idea:
flex: 1; will always allocate only 1/3rd of the width to the title. So use flex: 1 1 auto; instead to allow the title to expand into all available space.
add min-width: fit-content; to the back button (so that the title will never cover the back button).
Add bonus styling in the case where the title is really, really long
span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class="header" style="display: flex;">
<span style="flex: 1; background: aqua; min-width: fit-content;">Back Button</span>
<span style="flex: 1 1 auto; text-align: center; background: beige;">Edit title to see behaviour whien title is very long</span>
<span style="flex: 1; background:red;"></span>
</div>

Related

Place Item to Bottom React Native

I'm creating a react native app i have a item - a plus button(shown in image)
I want this to the bottom of my page onto footer -
but the problem is that when i place this button on bottom with position: 'absolute', bottom: 0 it's only going to the bottom of the hero section & not to the footer
Code -
<View style={styles.main}>
<View style={styles.hero}>
<View style={styles.flex}>
<View style={styles.container}>
</View>
</View>
<View style={styles.flex2}>
</TouchableOpacity>
</View>
<View style={styles.container12}>
</View>
</View>
</View>
<TouchableOpacity>
<View style={styles.container33}>
<EntypoIcon name="plus" style={styles.icon28}></EntypoIcon>
</View>
</TouchableOpacity>
Main Styles -
main: {
width: '100%',
height: '100%',
},
hero: {
alignSelf: 'stretch',
height: 250,
backgroundColor: '#fff',
borderBottomLeftRadius: 50,
borderBottomRightRadius: 50,
},
container33: {
width: 50,
height: 50,
backgroundColor: '#1DA6FA',
// flex: 1,
borderRadius: 50,
position: 'absolute',
bottom: 0,
right: 10,
alignItems: 'center',
justifyContent: 'center'
},
The problem si that you are applying the absolute css position to the View inside the TouchableOpacity and not to the TouchableOpacity itself.
To achieve what you want to do, you should write something like:
<View style={styles.absoluteOpacity}>
<TouchableOpacity>
<View style={styles.container33}>
<EntypoIcon name="plus" style={styles.icon28}></EntypoIcon>
</View>
</TouchableOpacity>
</View>
And then the css:
container33: {
width: 50,
height: 50,
backgroundColor: '#1DA6FA',
// flex: 1,
borderRadius: 50,
right: 10,
alignItems: 'center',
justifyContent: 'center'
},
absoluteOpacity: {
position: 'absolute',
bottom: 0,
}

Vertically center image that's not affected by KeyboardAwareScrollView in React Native

Alright, so this has got me busy for quite a few hours already. I am trying to create a login screen where the main components are rendered on the bottom, with the logo in the remaining space. This is kind of what I would like to achieve:
To support my textinputs, I use KeyboardAwareScrollView, as it works better for me as opposed to KeyboardAvoidingView. My code currently looks like this (I plan on using a background image with a 50% color overlay rather than the red background, so the ImageBackground has to stay in place too):
<ImageBackground
source={require('./assets/img/background-clouds.png')}
resizeMode="cover"
style={styles.backgroundImage}>
<View style={styles.backgroundOverlay} />
<View style={styles.dummyView}>
<Text>elloha</Text>
</View>
<Image
source={require('./assets/img/logo.png')}
style={styles.backgroundLogo}
resizeMode="contain"
/>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="always"
keyboardOpeningTime={0}
alwaysBounceHorizontal={false}
alwaysBounceVertical={false}
contentInsetAdjustmentBehavior="automatic"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
automaticallyAdjustContentInsets={false}
extraScrollHeight={30}
enableOnAndroid>
<StatusBar
backgroundColor="transparent"
barStyle="light-content"
hidden={false}
translucent
/>
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
accessible={false}>
<View style={styles.content}>
<View style={styles.backgroundContainer}>
<SafeAreaView style={{ flex: 0 }} />
<View style={styles.loginContainer}>
<View style={styles.loginScreen}>
// textinputs and buttons go here
</View>
<SafeAreaView style={{ backgroundColor: 'white' }} />
</View>
<View
style={{
backgroundColor: 'white',
height: Dimensions.get('window').height,
position: 'absolute',
width: Dimensions.get('window').width,
top: Dimensions.get('window').height,
}}
/>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAwareScrollView>
</ImageBackground>
Relevant styles:
const styles = StyleSheet.create({
container: {
backgroundColor: "white",
},
content: {
flex: 1,
},
backgroundImage: {
flex: 1,
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
backgroundContainer: {
justifyContent: "flex-end",
flex: 1,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
backgroundOverlay: {
backgroundColor: "red",
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
},
logoContainer: {
top: "10%",
width: "100%",
},
backgroundLogo: {
alignSelf: "center",
position: "absolute",
width: 126,
height: 96,
},
dummyView: {
backgroundColor: "red",
flex: 1,
},
loginContainer: {
borderTopEndRadius: 30,
borderTopStartRadius: 30,
width: "100%",
backgroundColor: "white",
height: 500,
alignItems: "center",
paddingTop: Dimensions.get("window").width * 0.1,
},
loginScreen: {
width: "80%",
backgroundColor: "white",
},
});
This yields the following result:
I can get it done by adding top: 160 to the backgroundLogo style, but that's a fixed value. I want it to be always in the center of the available space, but I'm unable to add a view between the background and the loginContainer, as all the logic for the keyboard and such is handled in between.
Is there a way to achieve what I want? Ideally, I should also be able to check the available height, and only show the logo if there is enough space (e.g. available height > 100, otherwise don't show logo).
Important:
I want the logo to stay fixed, so if the keyboard is shown, the logo should not move up. The loginContainer should go "over" the logo
EDIT:
Wrap Image inside a View with this style and give the loginContainer style height: '70%' :
...
<View style={styles.dummyView}>
<Text>elloha</Text>
</View>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
height: '30%',
position: 'absolute',
width: '100%',
}}>
<Image
source={require('./assets/img/logo.png')}
style={styles.backgroundLogo}
resizeMode="contain"
/>
</View>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="always"
...
...
loginContainer: {
borderTopEndRadius: 30,
borderTopStartRadius: 30,
width: '100%',
backgroundColor: 'orange',
height: '70%',
alignItems: 'center',
paddingTop: Dimensions.get('window').width * 0.1,
},
...
hie! I think using Dimension to get a specific screen's height and deciding it has 70% of the screen covered via form sheet and rest is free for a logo to be in and we can ask it to be down a little using rest of height's 50% as margin-top ( the image will be in the center of that image )
here is a SNACK LINK to see your example working with my suggested solution.
here is the draft code:
import * as React from 'react';
import { Text, View, StyleSheet, Dimensions, ImageBackground,TextInput,
Image, TouchableWithoutFeedback, Keyboard, SafeAreaView, StatusBar} from 'react-native';
import Constants from 'expo-constants';
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
export default function App() {
return (
<ImageBackground
source={{
uri: 'https://cdn.pixabay.com/photo/2021/08/23/18/37/tea-6568547_960_720.jpg',
}}
resizeMode="cover"
style={styles.backgroundImage}>
<View style={styles.backgroundOverlay} />
<Image
source={require('./assets/snack-icon.png')}
style={styles.backgroundLogo}
resizeMode="contain"
/>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="always"
keyboardOpeningTime={0}
alwaysBounceHorizontal={false}
alwaysBounceVertical={false}
contentInsetAdjustmentBehavior="automatic"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
automaticallyAdjustContentInsets={false}
extraScrollHeight={30}
enableOnAndroid>
<StatusBar
backgroundColor="transparent"
barStyle="light-content"
hidden={false}
translucent
/>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.content}>
<View style={styles.backgroundContainer}>
<SafeAreaView style={{flex: 0}} />
<View style={styles.loginContainer}>
<View style={styles.loginScreen}>
<TextInput value={'email'} style={{borderBottomWidth:1, padding:10}}/>
<TextInput value={'password'} style={{borderBottomWidth:1, padding:10}}/>
</View>
<SafeAreaView style={{backgroundColor: 'white'}} />
</View>
<View
style={{
backgroundColor: 'white',
height: Dimensions.get('window').height,
position: 'absolute',
width: Dimensions.get('window').width,
top: Dimensions.get('window').height,
}}
/>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAwareScrollView>
</ImageBackground>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'white',
},
content: {
flex: 1,
},
backgroundImage: {
flex: 1,
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
backgroundContainer: {
justifyContent: 'flex-end',
flex: 1,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
backgroundOverlay: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
},
logoContainer: {
top: '10%',
width: '100%',
},
backgroundLogo: {
alignSelf: 'center',
position: 'absolute',
marginTop: Dimensions.get('window').height/7, // top for rest of the screen to push logo down
width: 126,
height: 96,
},
dummyView: {
backgroundColor: 'red',
flex: 1,
},
loginContainer: {
borderTopEndRadius: 30,
borderTopStartRadius: 30,
width: '100%',
backgroundColor: 'white',
height: Dimensions.get('window').height/1.5, //container of form height
alignItems: 'center',
paddingTop: Dimensions.get('window').width * 0.1,
},
loginScreen: {
width: '80%',
backgroundColor: 'white',
},
});
Here is the output of code on android/ios:

React Native: Vertically and Horizontally align image and text in same row

<View>
<Text>Hello</Text>
<Image source={require('./Vector.png')} />
</View>
I have the above View. I want to vertically and horizontally align image and text. Image should be on the right and text left in the same row. But I am not able to do align them correctly.
You can check here live dmeo here expo-snack:
Also the code is pretty ismple :
import * as React from 'react';
import { Text, View, StyleSheet,Image } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Hey</Text>
<Image source={{uri:'https://source.unsplash.com/random'}} style={{height:50,width:50}}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'space-between',
backgroundColor: '#ecf0f1',
padding: 8,
flexDirection:'row',
alignItems:'center'
}
});
hope it helps. feel free for doubts , and if you want the text and image to be not so distant you can have justifyContent: 'center',
For horizontal:
flexDirection: 'row',
For vertical:
flexDirection: 'column',
Use flexDirection: 'row' to make it in the same row & use justifyContent: 'center', alignItems: 'center' to align it vertically & horizontally.
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
<Text>Hello</Text>
<Image style={{ width: 50, height: 50 }} source={require('./Vector.png')} />
</View>
You can simply do it by using flexDirection
Example :
<View
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
}}
>
<Text>Hello</Text>
<Image
style={{ width: 30, height: 30, resizeMode: "contain" }}
source={require("./Vector.png")}
/>
</View>
If you want to make the image right corner on the screen and text on the left corner try this. It can be done using position
<View
style={{
flex: 1,
flexDirection: "row"
}}
>
<Text style={{ position: "absolute", right: 0 }}>Hello</Text>
<Image
style={{
width: 30,
height: 30,
resizeMode: "contain",
position: "absolute",
left: 0
}}
source={require("./Vector.png")}
/>
</View>

Rendering two images in one row react native

I have visited so many websites and read many articles but couldn't find any solution. I want a ui in which each row contains two images. I have done this by adding view tag in every new row but i want to do in in a single View tag. Kindly help
<View style={{ marginTop: 10 }}>
<View style={{ flexDirection: 'row', justifyContent: "space-between" }}>
<View style={{ flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 5, alignSelf: 'flex-start' }}>
<Image
resizeMode="stretch"
source={require('../assets/images/Home/zinger_ratha.jpg')}
style={{ width: width / 2.2, height: width / 2, resizeMode: 'stretch', }} />
<Text style={{ fontSize: 18 }}>Zinger Ratha</Text>
</View>
<View style={{ flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 5, alignSelf: 'flex-start' }}>
<Image
source={require('../assets/images/Home/arabian_delight.png')}
style={{ width: width / 2.2, height: width / 2, resizeMode: 'stretch' }} />
<Text style={{ fontSize: 18 }}>Arabian Delight</Text>
</View>
</View>
<View style={{ flexDirection: 'row', justifyContent: "space-between" }}>
<View style={{ flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 5, alignSelf: 'flex-start' }}>
<Image
resizeMode="stretch"
source={require('../assets/images/Home/mingle_bucket.jpg')}
style={{ width: width / 2.2, height: width / 2, resizeMode: 'stretch', }} />
<Text style={{ fontSize: 18 }}>Mingle Bucket</Text>
</View>
<View style={{ flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 5, alignSelf: 'flex-start' }}>
<Image
source={require('../assets/images/Home/xtreme_box.jpeg')}
style={{ width: width / 2.2, height: width / 2, resizeMode: 'stretch' }} />
<Text style={{ fontSize: 18 }}>Xtreme Box</Text>
</View>
</View>
</View>
I want like this but in single View tag
You can do the following:
import Dimensions from react-native,
The idea here is to give the View a width of whatever percentage of the phone screen size and then give the image a percentage of the View that would give you what you want.
For example, if I want to display three images in a row, I can give my View a width of 90% and flexWrap: wrap, and give each image inside it a width of 30% so it can only contain 3 images in a row.
You can do the following for your case.
import { Dimensions } from 'react-native';
const { width, height } = Dimensions.get('screen');
// inside your render or return
<View style={{ width: width * 0.9, display: "flex", flexDirection: "row", flexWrap: "wrap", alignContent: "center", alignItems: "center", justifyContent: "center" }}>
<Image source={require("img.png")}style={{ width: "45%", height: 200 }} />
<Image source={require("img.png")}style={{ width: "45%", height: 200 }} />
<Image source={require("img.png")}style={{ width: "45%", height: 200 }} />
<Image source={require("img.png")}style={{ width: "45%", height: 200 }} />
</View>
or if you need to put it in a flatlist you can do something like this:
numColumns={2} // you need to specify the number of columns here
<FlatList
style={styles.dashboard}
data={this.categories}
renderItem={this.renderItem}
keyExtractor={item => item.id}
numColumns={2}
/>

How to make image resize in Animated.Image?

when I use <Image /> tag it has resizeMode='contain' to resize image. However, <Animated.Image /> doesnt have. so I cant adjust my image size. How can i solve this ?
<View style={{ backgroundColor: 'black', flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<StatusBar hidden />
<Animated.Image
source={require('../Image/img.png')}
style={{
height: 100, width: '80%', opacity: this.opacityValue,
transform: [{ scale: rotateX }],
}} >
</Animated.Image>
</View>
i did this however it isnt good solution. It can seem bad on other phones
this can help you scale the image and still retain resizeMode='contain'
<View style={{ backgroundColor: 'black', flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<StatusBar hidden />
<Animated.View style={{ transform: [{ scale: rotateX }] }}>
<Image
source={require('../Image/img.png')}
resizeMode='contain'
style={{
height: 100, width: '80%', opacity: this.opacityValue,
}} >
</Image>
</Animated.View>
</View>