Styling props not working, especially padding - css

I am still new to react-native and I have some troubles regarding the styling props of react-native.
I created a screen in my app and all my relevant code is this:
import React, {useState, useEffect} from 'react';
import {View, Text, StyleSheet, ActivityIndicator, Alert, ImageBackground} from 'react-native';
import { TextInput } from 'react-native-gesture-handler';
import {useDispatch, useSelector} from 'react-redux';
const NewLetterScreen = props =>{
return(
<View style={{flex:1}}>
<ImageBackground source={require('../components/pictures/welcome.png')} style={{width:"100%", height:"100%", alignItems: 'center', justifyContent: 'center'}}>
<ImageBackground source={require('../components/pictures/letters/paper1.jpg')} style={styles.paper}>
</ImageBackground>
</ImageBackground>
</View>
)
};
const styles = StyleSheet.create({
paper:{
width: "90%",
height: "90%"
}
});
export default NewLetterScreen;
The problem I face now is, that the "paper" I want to display is not centered, even tho I stricly declare this in the wrapping ImageBackground with justifyContent and alignItems. It is displaced to far up and to far on the left side and looks like this:
Also, if I try to use padding to get this stuff centered somehow, it doesnt work. I want to do padding from left and right, so horizontaly, but if I apply "paddingHorizontal: 50" to my styles.paper, the result is the following:
As you see, the "paddingHorizontal:50" works like a paddingLeft and that is definitely not what I intend.
I would be happy about any help regarding my styling props. Thanks in advance!

Why not add a margin of 10%? I always have problems with paddings. Try to avoid them.
Edit: Maybe it would help to just add a margin, instead of changing the width to 90%?
import React from "react";
import { ImageBackground, StyleSheet, Text, View } from "react-native";
const image = { uri: "https://reactjs.org/logo-og.png" };
const App = () => (
<View style={styles.container}>
<ImageBackground source={image} style={styles.image}>
<Text style={styles.text}>Inside</Text>
</ImageBackground>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
justifyContent: "center"
},
image: {
flex: 1,
resizeMode: "cover",
justifyContent: "center",
margin: "10%"
},
text: {
color: "white",
fontSize: 42,
fontWeight: "bold",
textAlign: "center",
backgroundColor: "#000000a0"
}
});
export default App;
You can copy&paste this example on https://reactnative.dev/docs/imagebackground

You just need to add a wrapper for the inside image. You don't need margins or paddings.
const image1 = { uri: "https://images.unsplash.com/photo-1597768130867-4c06bf86a2f3?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80" };
const image2 = { uri: "https://images.unsplash.com/photo-1611085857146-7b13f8b0a74f?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=641&q=80" };
const App = () => (
<View style={{ flex: 1 }}>
<ImageBackground source={image1} style={styles.background}>
<View style={styles.wrapper}>
<ImageBackground source={image2}
resizeMode="cover"
style={styles.paper}>
</ImageBackground>
</View>
</ImageBackground>
</View>
);
const styles = StyleSheet.create({
background: {
width: "100%",
height: "100%",
alignItems: 'center',
justifyContent: 'center'
},
wrapper: {
width: "90%",
height: "90%",
alignItems: 'center',
justifyContent: 'center',
},
paper: {
width: "100%",
height: "100%"
}
});

Related

flex-direction row not working in React Native

I'm trying to create an Andy Warhol style image for an assignment.
The row container isn't rendering the images in a row, the goal being to stack the 2 row containers in to a square formation.
Here's my code so far:
import React, { Component } from 'react';
import { AppRegistry, Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<View style = {styles.rowContainer}>
<View style = {styles('blue').img}>
<View style = {styles('red').subImg}>
</View>
</View>
<View style = {styles('black').img}>
<View style = {styles('green').subImg}>
</View>
</View>
</View>
<View style = {styles.rowContainer}>
<View style = {styles('purple').img}>
<View style = {styles('yellow').subImg}>
</View>
</View>
<View style = {styles('orange').img}>
<View style = {styles('#11E1E4').subImg}>
</View>
</View>
</View>
</View>
);
}
}
const styles = (inputColor) => StyleSheet.create({
container: {
flex : 1,
flexDirection: "row",
},
rowContainer:{
height: 100,
width: 200,
flexDirection: "row",
},
img: {
height : 100,
width: 100,
alignItems: "center",
justifyContent: "center",
backgroundColor : inputColor,
},
subImg: {
height: 50,
width: 50,
backgroundColor : inputColor,
},
});
I've fiddled around with the nesting and the size of the row containers. The example code given to me by my teacher works as expected. I have no clue what is going wrong. Really new to coding btw so please dumb any answer down
Example Code:
import React, { Component } from 'react';
import { AppRegistry, Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.topBox}>
</View>
<View style={styles.middleBox}>
</View>
<View style={styles.bottomBox}>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
},
topBox: {
width: 75,
height: 75,
backgroundColor: 'lightblue',
},
middleBox: {
width: 75,
height: 75,
backgroundColor: 'mediumblue',
},
bottomBox: {
width: 75,
height: 75,
backgroundColor: 'darkblue',
},
});
If you use styles as a function then you need to call it when applying styles.
Add () after styles.
<View style={styles().container}>
<View style = {styles().rowContainer}>
Using typescript can help to avoid such errors.
You are not using flexbox. This is done by setting display: flex on the container. Therefore, set display: "flex" on the container.
const styles = StyleSheet.create({
container: {
display: 'flex',
flex: 1,
flexDirection: 'column',
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
},
...
Side note: When setting display: flex, the flex-direction (flexDirection) is row by default.

overflow:hidden not working on imagebackground

<ImageBackground
source={require('../../assets/frame.png')}
style={{
justifyContent: 'center',
alignItems: 'center',
height: 50,
width: 50
}}
>
<Image
source={
userData && userData?.avatar
? { uri: userData?.avatar }
: require('../../assets/avatar.png')
}
style={{
height: '100%',
width: '100%'
}}
/>
</ImageBackground>
I'm trying to put the image inside the frame and remove the overflow, how can I achieve that?
you can see it's extending past the frame
see the thing is the frame itself doesnt take the entire space, since its an image, and background image doesnt respect overflow:
Here is the solution
Ive just made resizeMode = "contain" and decreased the height relatively of player image.
Hope it works, feel free for doubts:
import * as React from 'react';
import { Text, View, StyleSheet, ImageBackground, Image } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App() {
return (
<View style={styles.container}>
<ImageBackground
source={require('./assets/frame.png')}
style={{
justifyContent: 'center',
alignItems: 'center',
height: 100,
width: 100,
overflow:'hidden',
backgroundColor:'yellow'
}}>
<Image
source={require('./assets/1659513190.png')}
style={{
height: '90%',
width: '100%',
overflow:'hidden',
marginBottom:10
}}
resizeMode="contain"
/>
</ImageBackground>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
// justifyContent: 'center',
alignItems:"center",
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});

React Native View shrinks to fit content when centered

I have a React Native View that I would like to have extend up to but not exceed a given width. Inside this View, I have a Text element that I would like to fill out the full width of its parent. It looks like this:
However, if I set the parent View to center align with alignSelf: 'center' the view will shrink to fit the text inside the Text view, like so:
Why does changing the alignment of a View cause it to change size, and how can I prevent this?
Expected Output:
Complete code to replicate this scenario:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.box}>
<Text style={styles.paragraph}>Text</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
box: {
backgroundColor: 'red',
height: 50,
maxWidth:200,
alignSelf: 'center' // <---REMOVE THIS LINE TO FILL VIEW
},
paragraph: {
textAlign: 'left',
backgroundColor: 'green',
},
});
Why adding width will not work
While setting a fixed width value would enforce the maximum size, it would prevent this element from shrinking down below that value. For this reason, specifying width is not a solution. Here is an example situation where the size of the view would extend past the display.
With width:
Expected:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.box}>
<Text style={styles.paragraph}>Text</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignContent:'center',//ADD THIS LINE
backgroundColor: '#ecf0f1',
padding: 8,
},
box: {
backgroundColor: 'red',
height: 50,
maxWidth:200,
},
paragraph: {
textAlign: 'left',
backgroundColor: 'green',
},
});
expo

React Native- image wont fill screen?

This is frustrating. I have an image the exact same dimensions as the screen (of this device) and moreover same dimensions as the splash image. I just want it to fill the whole screen, above the other Views, for a few seconds after the splash goes away in order to do a custom animation.
Looking at other SO questions, Ive tried this so far (outside the main container of other app elements):
<Animated.View style = {styles.splash}>
<Image style = {{resizeMode: 'cover'}} source={require('./assets/splash2-txt.png')}/>
</Animated.View>
splash: {
flex: 1,
position: 'absolute',
zIndex: 4
},
and yet the image is scaled up and way off to the corner.
What is wrong here / how can I just fill the screen with the image?
Please use react-native ImageBackground for filling image in background, refer the example code given below
import React from "react";
import { ImageBackground, StyleSheet, Text, View } from "react-native";
const image = { uri: "https://reactjs.org/logo-og.png" };
const App = () => (
<View style={styles.container}>
<ImageBackground source={image} style={styles.image}>
<Text style={styles.text}>Inside</Text>
</ImageBackground>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column"
},
image: {
flex: 1,
resizeMode: "cover",
justifyContent: "center"
},
text: {
color: "grey",
fontSize: 30,
fontWeight: "bold"
}
});
export default App;
Use StyleSheet.absoluteFillObject in your image style instead of flex.
It should be something like...
import * as React from 'react';
import { Image, View, StyleSheet, StatusBar } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<StatusBar barStyle="light-content" />
<Image style={styles.image} source={{uri: 'https://reactjs.org/logo-og.png'}} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
image: {
...StyleSheet.absoluteFillObject,
resizeMode: 'cover',
},
});

I need an image to take up the maximum space it can regardless of its original size

I am developing a react-native application and I have a top bar and a bottom bar. There is an image between these two bars, and I need it to take up the maximum space it can regardless of the images original size without getting in the way of the two bars. I've been trying for a while and I can't figure out how to do this.
I have tried a bunch of things with flexbox and setting the image size, but I can't get it to work.
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import Topbar from './topbar.js'
export default function App() {
return (
<View style = {{
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between'
}}>
<View>
<Topbar />
</View>
<View>
<Image source={require('./image2.jpg')} />
</View>
<View>
<Topbar />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
// here are my bars
import React, { Component } from "react";
import {
Image, StyleSheet, View, Text,Dimensions
} from "react-native";
import Animated from "react-native-reanimated";
const {screenwidth, screenheight } = Dimensions.get("window");
export default class Topbar extends Component {
render() {
return (
<View style ={{
width: screenwidth,
height: 80,
backgroundColor: "#C0C0C0",
flexDirection: 'row',
justifyContent: 'space-between',
}}>
</View>
)
}
}
const styles = StyleSheet.create({
topbarbackground: {
width: screenwidth,
height: 80,
backgroundColor: "#C0C0C0",
}
})
I need to see the bars and the image and it has to take up the entirety of the phone screen.
I'm not pretty sure what you are trying to get. You can try using ImageBackground component and set the resizeMode to cover. Example:
Cover the entire Screen
<ImageBackground
source={img}
imageStyle={{ resizeMode: 'cover' }}
style={{ width: '100%', height: '100%' }}>
<Topbar/>
<View style={{ flex: 1 }}/>
<Bottombar/>
</ImageBackground>
Cover the available space
<View style={{ flex: 1 }}>
<Topbar/>
<ImageBackground
source={img}
imageStyle={{ resizeMode: 'cover' }}
style={{ width: '100%', flex: 1 }}/>
<Bottombar/>
</View>

Resources