Component won't stay wrapped within bounds (React Native) - react-native

I am trying to make my own tab navigation like Instagram has instagram example. I noticed that the items within the footer view I made does not stay within the bounds and moves to the top left of the screen. Images shown - What I am trying to achieve What happens frequently
Here is the most important part of my code. I have done inline styles temporarily to try and figure out the issue. Here is the part where the issue lays <View style = {{ width: Dimensions.get('window').width, backgroundColor: '#fff', height: 80}} <TouchableOpacity onPress = {() => this.props.navigation.navigate('Profile')} style = {{justifyContent: 'flex-end'}}>
<Text style = {{justifyContent: 'flex-end'}}> Profile </Text>
</TouchableOpacity> </View>-
render() {
return (
<MapView style = {[style.container, style.map]}
region = {this.state.initialPosition}>
<MapView.Marker coordinate = {this.state.markerPosition}>
<View style = {style.radius}>
<View style = {style.marker}/>
</View>
</MapView.Marker>
<View style = {{ width: Dimensions.get('window').width, backgroundColor: '#fff', height: 80}} >
<TouchableOpacity onPress = {() => this.props.navigation.navigate('Profile')} style = {{justifyContent: 'flex-end'}}>
<Text style = {{justifyContent: 'flex-end'}}> Profile </Text>
</TouchableOpacity>
</View>
</MapView>
);
}
}
const style = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-end',
//alignItems: 'center',
},
text: {
color: '#fff'
},
map: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute'
},
radius:{
height: 50,
width: 50,
borderRadius: 50 / 2,
overflow: 'hidden',
backgroundColor: 'rgba(1,213,106,0.3)',
borderWidth: 1,
borderColor: 'rgba(1,213,106,0.3)',
alignItems:'center',
justifyContent: 'center'
},
marker: {
height: 20,
width: 20,
borderWidth: 3,
borderColor: '#fff',
borderRadius: 20 / 2,
borderWidth: 3,
overflow: 'hidden',
backgroundColor: '#01D56A'
},
menuSection: {
backgroundColor: 'rgba(255, 255, 255, 0.7)',
width: Dimensions.get('window').width,
height: Dimensions.get('window').height/3,
justifyContent: 'flex-end',
alignItems: 'center'
},
icon:{
width: 50,
height: 50,
backgroundColor: 'black'
}
})

Related

Underline behind text React Native

I want to make a specific underline behind text in a specific area of the title, like this:
How do I do it with React Native?
This is the situation right now:
<View style={[styles.container, {width}]}>
<Image source={item.image} style={[styles.image, {width, resizeMode: 'contain'}]}/>
<View style={{flex: 0.2}}>
<Text style={[styles.title]}>{item.title}</Text>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
image: {
flex: 0.6,
justifyContent:'center'
},
title: {
fontWeight: "600",
fontSize: "26",
color: 'black',
textAlign: 'center',
}
})
I've seen this thread with css Thick underline behind text
You have to position the title absolute to achieve that.
In the following code, I have implemented an example I hope it will help you.
<View style={{marginTop: 20, height: 200, position: 'relative'}}>
<View style={styles.line}></View>
<Text style={styles.title}>Specific Title</Text>
</View>
const styles = StyleSheet.create({
title: {
fontSize: 44,
fontWeight: '500',
lineHeight: 45,
position: 'absolute',
top: 20,
},
line: {
marginTop: 40,
marginLeft: 50,
borderRadius: 10,
height: 15,
width: 100,
backgroundColor: '#3F8ED6',
},
})
result

Elevation doesn't work properly react native

I am trying to give shadow to my custom card component but the shadow cuts down the view like this:
Here is my code
import React from 'react'
import { View, StyleSheet, Text, Image, Dimensions } from 'react-native'
const { width } = Dimensions.get('window')
export default function CardCus() {
return (
<View style={{
justifyContent: 'center', alignItems: 'center', padding: 10
}}>
<View style={styles.container}>
<View style={{ width: 110, borderTopLeftRadius: 10, borderBottomLeftRadius: 10, }}>
<Image style={{ width: '100%', height: '100%', borderTopLeftRadius: 10, borderBottomLeftRadius: 10 }} source={{ uri: 'https://images.pexels.com/photos/6231818/pexels-photo-6231818.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940' }} />
</View>
<View style={{ margin: 10, padding: 5 }}>
<Text style={styles.title}>Title</Text>
<Text>Separator</Text>
<Text>Title</Text>
<Text>Title</Text>
</View>
</View>
</View>
)
}
const styles = StyleSheet.create(
{
container: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 2,
elevation: 2,
flexDirection: 'row',
borderRadius: 10,
borderColor: 'black',
borderWidth: 1,
height: 110,
width: width - 10,
},
title: {
fontWeight: 'bold'
}
}
)
I have tried many different style settings but none of them work. Is there a way to solve this issue? Thanks in advance.
So related to your question, it was hard to understand at first.
I just added the properties zIndex and backgroundColor to the container style and increased the value of the elevation and now it looks better. Also improved the readability.
See the comments in the improved code below:
import React from 'react';
import { View, StyleSheet, Text, Image, Dimensions } from 'react-native';
export default function CardCus() {
const imgUri =
'https://images.pexels.com/photos/6231818/pexels-photo-6231818.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940';
return (
<View style={styles.main}>
<View style={styles.container}>
<View style={styles.imageContainer}>
<Image style={styles.image} source={{ uri: imgUri }} />
</View>
<View style={styles.textContainer}>
<Text style={styles.title}>Title</Text>
<Text>Separator</Text>
<Text>Title</Text>
<Text>Title</Text>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 2,
elevation: 10, // changed to a greater value
flexDirection: 'row',
borderRadius: 10,
borderColor: 'black',
borderWidth: 1,
height: 110,
width: Dimensions.get('window').width - 10,
zIndex: 99, // added zIndex
backgroundColor: 'white', // added a background color
},
title: {
fontWeight: 'bold',
},
imageContainer: {
width: 110,
borderTopLeftRadius: 10,
borderBottomLeftRadius: 10,
backgroundColor: 'white',
},
image: {
width: '100%',
height: '100%',
borderTopLeftRadius: 10,
borderBottomLeftRadius: 10,
},
textContainer: {
margin: 10,
padding: 5,
backgroundColor: 'white',
},
main: {
justifyContent: 'center',
alignItems: 'center',
padding: 10,
},
});
You can adjust the values to make the shadow darker. And this is how it looks:

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 - issue with flexDirection

I am trying to put a button (custom component made from TouchableOpacity inside View) and an image in a view.....and have them sit side by side.
See code below
<View
style={{
borderColor: 'black',
borderWidth: 1,
flex: 1,
flexDirection: 'row',
}}
>
<MyButton
to_extraStyle={{
backgroundColor: '#03A9F4',
width: 100,
height: 60,
alignSelf: 'flex-start',
}}
onPress={this._imagePickHandler}
>
CHOOSE PIC
</MyButton>
<Image
source={{ uri: this.state.localImgUrl }}
style={{
width: 100,
height: 60,
borderColor: 'black',
borderWidth: 1,
alignSelf: 'flex-end',
}}
/>
</View>
When I remove flexDirection: 'row' you can see both the image and the button....they sit on top of each other....but with flexDirection: 'row' included, the image disappears and you can only see the button.
Any ideas?
Use the value of width as %.
<View
style={{
borderColor: 'black',
borderWidth: 1,
flex: 1,
flexDirection: 'row'
}}
>
<MyButton
to_extraStyle={{
backgroundColor: '#03A9F4',
width: "50%",
height: 60,
}}
onPress={this._imagePickHandler}
>
CHOOSE PIC
</MyButton>
<Image
source={{ uri: this.state.localImgUrl }}
style={{
width: "50%",
height: 60,
borderColor: 'black',
borderWidth: 1,
}}
/>
</View>
Example
export default class App extends Component {
render() {
return (
<View style={s.container}
>
<TouchableOpacity style={s.touchable}>
<Text style={{color:"#ffffff"}}>Button </Text>
</TouchableOpacity>
<Image source={{uri: 'http://i.imgur.com/IGlBYaC.jpg'}} style={s.backgroundImage} />
</View>
);
}
}
const s = StyleSheet.create({
backgroundImage: {
width: "50%",
height: 60,
borderColor: 'black',
borderWidth: 1,
},
touchable: {
backgroundColor: '#03A9F4',
width: "50%",
height: 60,
justifyContent:"center",
alignItems:"center"
},
container: {
borderColor: 'white',
borderWidth: 1,
flex: 1,
flexDirection: 'row'
}
});
Remove alignSelf on both MyButton and Image and they will sit side by side.
If what you wanted to obtain with alignSelf is to align MyButton at the very left and Image at the very right then add justifyContent: 'space-between' to your view.

View over another view in percentage of screen width

I am new in react native and i want a view like attached image. I have no idea that how can achieved this..?
I have tried this:
app.js
<View style={styles.navSectionStyle}>
<TouchableOpacity
style={styles.SubmitButtonStyle}
activeOpacity = { .5 }
onPress={ this.ButtonClickCheckFunction }>
<Text style={styles.TextStyle}> Page 1 </Text>
</TouchableOpacity>
<View style={styles.BackStyle}>
<Text style={styles.TextStyle}> Test</Text>
</View>
</View>
style.js
SubmitButtonStyle: {
width:'70%',
height: 80 ,
justifyContent: 'center',
alignItems: 'center',
paddingTop:15,
paddingBottom:15,
backgroundColor:'#fff',
borderRadius:10,
borderWidth: 2,
borderColor: '#fff'
},
BackStyle:{
marginTop:10,
marginLeft:15,
position: 'absolute',
width: 30,
borderRadius:10,
borderWidth: 1,
borderColor: '#F53BBB',
backgroundColor: '#F53BBB',
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000000',
shadowOffset: {
width: 2,
height: 3
},
shadowRadius: 4,
shadowOpacity: 1.0
},
TextStyle:{
justifyContent: 'center',
alignItems: 'center'
}
Here's a basic template for the View
Get the Width of the screens using Dimensions api.
Mark the views as position: absolute and get position them according to the screen width.
15 % from both sides, 10% for overlapping view and 60% for the main view
render() {
return (
<View style={{flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'red'}}>
<View style={{width: Dimensions.get('window').width * 0.6,
height: 100,
backgroundColor: 'blue'}}/>
<View style={{position: 'absolute',
width: Dimensions.get('window').width * 0.1,
height: 80,
backgroundColor: 'black',
left: Dimensions.get('window').width * 0.15,
zIndex: 1}} />
<View style={{position: 'absolute',
width: Dimensions.get('window').width * 0.1,
height: 80,
backgroundColor: 'black',
right: Dimensions.get('window').width * 0.15,
zIndex: 1}} />
</View>
)
}