React Native - Image inside Nested Text, Vertical Align not working - react-native

const styles = StyleSheet.create({
container: {
fontSize: 15,
alignItems: 'center',
justifyContent: 'center',
},
insideText: {
width: 30,
height: 30,
alignSelf: 'center',
},
})
<Text style={styles.container}>
<Image style={styles.insideText} source={myImage} />
test
</Text>
When I implement this functionality with Swift
Fixed by setting NSAttachment bounds.
But React Native does not know how to access those parameters.
The output of my code.
How do I center text and images?
can not divide a view into several.
Because the content is flexible, it is not known how many it will be.
Smaller image sizes will center them
The image is too small.
I want to keep the image size.

It's probably not the nicest way but you could do this:
const styles = StyleSheet.create({
container: {
fontSize: 15,
height: 30,
paddingTop: (30 - 15) / 2,
paddingLeft: 30
},
insideText: {
width: 30,
height: 30,
position: 'absolute',
left: 0,
top: 0,
},
})

Not exactly sure what you mean by the requirement of flexible content, but nesting an Image within a text does not seem like the way to go.
You'll have less styling flexibility, and are very limited.
To affect what you want without setting absolute positioning, just wrap it and have the icon and text as siblings of a parent View:
<View
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
}}>
<Image style={styles.insideText} source={snackIcon} />
<Text style={styles.container}>test</Text>
</View>
Fortunately your styles for insideText and container are fine for this example :)
Here's a snack of the code:
https://snack.expo.io/#paullyfire/centered-image-text-container
Let me know if you have any issues.

Related

Adding a overlaying shadow on an image

I am trying to create a shadow over the bottom part of an image like in the example I have provided. I was thinking about just overlaying a linear gradient and changing the opacity maybe, I am not even sure how accurately this would portray it but I am assuming there is a better way.
To be clear, I do NOT want to create a shadow on the outside of the image, I want it to overlay the image.
Thank you guys for any insight at all!
Linear Gradient to achieve using expo linear gradient
<View style={{borderBottomLeftRadius: 30, borderBottomRightRadius: 30, overflow: 'hidden', top: 125}}>
<LinearGradient
colors={['transparent', 'rgba(0,0,0,0.4)', ]}
style={{width: 300, height: 100,}}>
</LinearGradient>
</View>
I found a good library here to use, the usage in their example provided exactly what I am looking for with easy to use props.
https://www.npmjs.com/package/react-native-inset-shadow
import React from "react";
import { View, Image, } from "react-native";
const ShadowExample = (props) => {
const imageURL = "https://designpress-10674.kxcdn.com/wp-content/uploads/2012/10/funny-horse-pictures/happy-to-see-you.jpg"
const localStyles = {
withShadowStyle: {
justifyContent: "center",
alignItems: "center",
backgroundColor: "white",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.50,
shadowRadius: 4,
elevation: 3,
},
};
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<View style={{ ...localStyles.withShadowStyle, padding: 10, }}>
<Image source={{ uri: imageURL, }} style={{ width: 200, height: 200, }} />
</View>
</View>
)
}
P.S. Check out the React Native shadow generator:
https://ethercreative.github.io/react-native-shadow-generator/

How to apply shadow to react native View without affecting inner view elements?

I would like to know how to apply shadow only to the main outer view. Here on applying shadow, it's getting applied to all the inner elements
The trick to make the shadow props of parent don't inherit to children element, is to set a background color to the component on which you set the shadow. For example that would be:
<View
style={{ backgroundColor: '#fff' }}
shadowOffset={{height: 10}}
shadowColor='black'
shadowOpacity={0.5}
>
<Text>{title}</Text>
</View>
Unfortunately this only works with colored backgrounds – when setting a transparent background with RGBA or 'transparent' is doesn't help.
I cannot really answer based on a simple image, but from my previous experience, setting shadow offset to the required height and width should do the trick for the iOS.
Read more about it here: Shadow Offset
Here's a picture of what my card looks like with the following style used:
marginLeft: 10,
backgroundColor: 'white',
shadowColor: 'blue',
alignItems: 'center',
shadowOffset: {width: 3, height: 3 },
shadowOpacity: 1.0,
borderRadius: 10,
My card View
Hope it works out well for you.
Display custom shadow color >= 28 or >= P for above Sdk level 28
Code
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View
style={{
shadowColor: 'purple',
height: 150,
width: '90%',
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
//android specific
elevation: 10,
//ios specific
shadowOffset: { width: 1, height: 1 },
shadowRadius: 3,
shadowOpacity: 0.5,
}}>
<Text style={{ color: 'rgba(128,0,128,0.5)' }}>
Welcome to React Native
</Text>
</View>
</View>
In android we can adjust shadow by elevation property
In iOS we can adjust shadow by shadowOffset, shadowRadius,shadowOpacity property
Output android
Output iOS
Available library for further usage
react-native-shadow-2
react-native-drop-shadow
Create a Shadow.js
export const Shadow = (elevation) => { // Receive elevation as a prop
return {
elevation,
shadowColor: 'black',
shadowOffset: { width: 0, height: 0.5 * elevation },
shadowOpacity: 0.3,
shadowRadius: 0.8 * elevation,
};
};
import Shadow.js to the page where you want to apply
import Shadow from './Shadow' //path to Shadow.js
<View style={{Shadow(5)}}> // pass elevation as a prop to Shadow.js
</View>
if you want to use in styles
import Shadow from './Shadow' //path to Shadow.js
<View style={styles.shadow}>
</View>
const styles = StyleSheet.create({
shadow:{
...Shadow(5) //use spread operator
}
});

react native,child's width by percentage

Here is my code. I want the product view to take up 90% width of its parent. However, the settings below are not working.
...any idea how to achieve it without using dimensions?
return (
<LazyloadScrollView
style={styles.container}
contentContainerStyle={styles.content}
name="scrollImage" >
{list.map((product, i) => <View key={i} style={styles.product}>
<LazyloadImage
host="scrollImage"
style={styles.image}
source={image}
animation={false}>
<View style={styles.id}>
<Text style={styles.idText}>{product.id}</Text>
</View>
</LazyloadImage>
</View>)
}
</LazyloadScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff'
},
content: {
paddingTop: 20,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#eee'
},
product: {
flex: 0.9,
marginTop: 5,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#FFFFFF'
},
Why not use Dimensions? It will enable your app to be responsive.
If you don't want to use dimensions, try some style settings in the container and it's children, for example, make it full width with padding
container: {
backgroundColor: '#ffffff',
alignSelf: 'stretch',
padding: 30
}
I don't know if it works because you would have to post the rest of the code to test it but keep playing with the style and flex properties until you make it work, shouldn't take long.
Btw, always good to revisit the official layout props docs from react native
And css tricks guide to flexbox

Style width using flex in React Native

I'm working in react native and I'm trying to style a component. I have a view (black border) that wraps two views (A and B). I would like something that looks like this - where I the view that wraps A has a width of about 75% and the view that wraps B has a width of about 25%.
When this component is rendered out as a list, however, what I'm getting is something like this - where the width of the A view is dependent on how much text it holds.
I was able to set the width to a specific amount, but it always seems to change based on the device I test it on (different on iPhone 5, 6, 6 plus, etc.). Therefore I'm trying to use flex styling, but can't seem to get it right. Here is my code for my styling and component structure:
const styles = StyleSheet.create({
title: {
color: '#000',
textAlign: 'left',
fontSize: 80,
},
row: {
flex: 1,
flexDirection: 'row',
padding: 0,
height: 180,
borderBottomColor: '#888',
borderBottomWidth: 1,
alignItems: 'stretch'
},
innerContainer: {
flex: 1,
padding: 0,
flexDirection: 'row',
alignItems: 'stretch',
},
sideDivider: {
flex: 0.8,
padding: 0,
backgroundColor: '#cacaca',
justifyContent: 'center'
},
sideDividerArrow: {
flex: 0.2,
padding: 0,
alignItems: 'center',
backgroundColor: 'cyan',
justifyContent: 'center',
},
});
...
render() {
return (
<View style={styles.row} ref={component => this._root = component}>
<TouchableHighlight onPress={this.handleClick.bind(this)}>
<View style={styles.innerContainer}>
<View style={styles.sideDivider}>
<Text style={styles.title}>
{this.state.routeData.busNumber}
</Text>
<Text>{this.state.routeData.fullRoute}</Text>
</View>
<View style={styles.sideDividerArrow}>
<Text>></Text>
</View>
</View>
</TouchableHighlight>
</View>
)
}
}
Any and all help is appreciated. Thanks!!
The flex attribute expects an integer. We cannot use fractions for it.
I guess rendering the following will help you achieve the desired look. You can then add your interactions and clean up the inline styles
<View style ={{flexDirection:'row',flex:1,borderColor:'black',borderWidth:1}}>
<View style ={{flex:3,backgroundColor:'blue',alignItems:'center',justifyContent:'center'}}>
<Text>A</Text>
</View>
<View style ={{flex:1,backgroundColor:'yellow',alignItems:'center',justifyContent:'center'}}>
<Text>B</Text>
</View>
</View>
Your picture has 3 components, but the code actually has more.
The code should work as intended if you do:
- row: flex: 1 (to make sure row is full width) + flexDirection: 'row' (so row children will be left to right).
- A container: flex: 3.
- B container: flex: 1.
At least one of the children of A or B should have a flex: 1 (or any other number) to ensure that children also stretch to fill the parent.
In your case, giving the title and the text components a flex: 1 property will probably do the trick.
Hope this helps!

How to stretch a static image as background in React Native?

I'd like to use a background image in my react native app,
the image is smaller than the screen, so I have to stretch it.
but it doesn't work if the image is loaded from asset bundle
var styles = StyleSheet.create({
bgImage: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'stretch',
resizeMode: 'stretch',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
<Image source={require('image!background')} style={styles.bgImage}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
</Image>
it looks like this:
however, it works fine for a remote image, through source={{uri: 'background-image-uri'}}:
From Github issue: Image {require} is broken in React Native for Resizing, you could try <Image style={{width: null, height: null}}, hope that facebook would fix it soon.
The Image tag should generally not be treated as a container view.
Having an absolutely positioned wrapper containing your (stretched/contained) image appears to work well:
var styles = StyleSheet.create({
bgImageWrapper: {
position: 'absolute',
top: 0, bottom: 0, left: 0, right: 0
},
bgImage: {
flex: 1,
resizeMode: "stretch"
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10
}
});
<View style={{ flex: 1 }}>
<View style={styles.bgImageWrapper}>
<Image source={require('image!background')} style={styles.bgImage} />
</View>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
</View>
You could always use the Dimensions module to get the width of the screen and set your image's width style to that value:
var Dimensions = require('Dimensions');
var {width, height} = Dimensions.get('window');
It also seems strange that a remote image works fine...you can try loading up a local static image with the uri syntax by using source={{uri: 'local_image_file_name' isStatic: true}}.
for me use undefined instead of null value. on typescript environment, it will be prompted not assignable
bgImage: {
flex: 1,
width: undefined,
height: undefined,
resizeMode: 'stretch',
},