Adding touchableOpacity to an Image component - reactjs

Simple question: How do I add a TouchableOpacity component to an image? This is the way I'm doing it:
<View style = { styles.categoryContainer }>
<TouchableOpacity
onPress = {() => navigation.navigate('xScreen')}
>
<Image
style = {styles.categoriesImages}
source = {require('./img/xImage.png')}
/>
</TouchableOpacity>
These are the styles that are mapped to the components:
categoryContainer: {
flex: 1,
flexDirection: 'column',
margin: 10,
},
categoriesImages: {
display: 'flex',
height: 70,
width: 70
},
When I run the app on expo, the image simply disappears. Removing the TouchableOpacity component brings the image back.
Maybe someone can provide an explanation as to why this doesn't work? Thanks a lot!

I'm just assuming this is the problem, but without the styles it's a bit hard to really know.
Basically your Image must have a width and height in percentage, and you wrapped the image with TouchableOpacity, which doesn't have "size". So you have two ways to solve your issue:
You map a style to TouchableOpacity with the width and height of your
styles.categoriesImages and the Image will simply have 100% on both
width and height
Define a width and height for the image that's not a percentage but an actual value, and the TouchableOpacity will simply adapt to it's content size

Related

TouchableOpacity breaks styling

I'm attempting to create navigation in React Native. I've made a custom component that consists of an image and some text. Before applying TouchableOpacity the styling works fine. But after I apply it to one of the components, this happens.
All of the code can be found here, ready to run.
I'd like that the component titles MojQR doesn't deform, but stays like the rest of them. Currently, as seen in the code, the TouchableOpacity is only applied to MojQR
You have a problem with the styling you are using. When you set the dimensions (width, height) to take a percentage, it will take the percentage from the component that is wrapping it. That's why when you added TouchableOpacity it mess all the styling. You have 2 options, change the styling pattern you are using or make a simple change that can change the width dynamically from MenuItem like so:
//App.js
<TouchableOpacity style={styles.touchableContainer} onPress={() => navigation.navigate('Details')}>
<MenuItem itemImage={require('./app/img/QR_code_for_mobile_English_Wikipedia.svg.png')} children='Moj QR' isWrapped={true} />
</TouchableOpacity>
...
//And the styling inside your style object
touchableContainer: {
width: '50%'
}
In the code above, you add that prop that will be used to change the styles in
//MenuItem.js
//change the wrapper for this one:
<View style={this.props.isWrapped ? {...styles.menuItem, width: '100%'} : styles.menuItem}>
...
//And add the flexGrow property to your styles.menuItem
menuItem: {
width: '50%',
height: '33.3333%',
padding: 10,
flexGrow: 1,
},

How do I work with background in React Native?

In my app, I want to create some sort of parallax effect, just like this, where the content overlap the background : video
This is what I made in Figma: figma prototype
And this is what I currently have : current prototype
How do I allow the content to go over the picture and how am I supposed to only have the bottom of the picture for the background ? (I don't want to cut it since it could mess on other devices)
Here is my code :
import React from 'react'
import {ImageBackground,View, ScrollView, Text, StyleSheet, Dimensions} from 'react-native'
import {generalStyles} from '#gym-app/styles/general'
export default function MuscleScreen() {
const Image = require('../assets/muscles/abs.jpg')
return (
<ScrollView>
<ImageBackground source={Image} style={styles.background}>
<View style={[generalStyles.container, styles.overlap]}>
<Text style={generalStyles.title}>Abdominaux</Text>
</View>
</ImageBackground>
</ScrollView>
)
}
const styles = StyleSheet.create({
background: {
width: Dimensions.get('window').width,
height: (Dimensions.get('window').width / 16 * 9),
resizeMode: 'cover'
},
overlap: {
position: 'absolute',
top: (Dimensions.get('window').width / 16 * 9),
width: Dimensions.get('window').width
}
})
Thank you for your help !
Put your ImageBackground behind the ScrollView, e.g.
<View>
<ImageBackground />
<ScrollView />
<View>
Give ScrollView absolute position taking entire screen
As a first item in ScrollView, add blank space (empty View) with height of a
window you want for the picture
Capture current scroll position of
ScrollView with Animated.event
Interpolate that value so that it scrolls up slightly slower than ScrollView and apply it as transform translateY of your ImageBackground

Is there a way to wrap background color around text in react-native?

Currently, this is what I am trying to avoid. As you can see the background color runs until the end of the width. It would be nice for the background color to surround the text.
I looked a tons of examples and I don't really see where they wrap background color around the text itself
<Text style={{backgroundColor:'blue'}}> TTeexxtt </Text>
I tried with flexWrap and it doesn't work just like so
<Text style={{backgroundColor:'blue', flexWrap:'wrap'}}> TTeexxtt </Text>
As always, thank you
Views in react native default to an alignItems prop of stretch. What does this mean though?
All children of your view will stretch to fill the width of their parent, with considerations for margin.
If you set the alignItems property of your parent view to something other than stretch, such as center, flex-start, or flex-end you will see the background color only extend around your actual text.
You can also use alignSelf on your Text views to adjust individual items.
Here is an example snack
https://snack.expo.io/#ajthyng/vengeful-celery
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
const BGText = props => {
const { background } = props;
return <Text style={{backgroundColor: background, ...props.style}}>{props.children}</Text>;
}
export default class App extends React.Component {
render() {
return (
<View style={{flex: 1, backgroundColor: 'white', alignItems: 'stretch', marginTop: 23}}>
<BGText background='pink' style={{marginRight: 16}}>I am some text</BGText>
<BGText background='orange' style={{alignSelf: 'flex-start', marginLeft: 16}} >My BG Color is short</BGText>
</View>
);
}
}

React Native Layout - Flexbox with responsive images

I'd like to achieve a layout with Flexbox in React Native. The idea is to be able to have a responsive image with text beneath it, vertically centered in on the page.
The issue seems that the View that contains the image, either ends up disappearing as the image has no height or filling the entire screen height and pushing the text that shoud be below the image down to the bottom.
I assume its to do with the image dimensions being undefined in order to get it to act in a responsive way and fill the parent container.
Here's a mockup of the layout
Update
Thanks Topik Mujianto - I was actually following that very tutorial!
Here's my code:
const styles = StyleSheet.create({
pageContainer: {
flex: 1,
flexDirection:'row',
justifyContent:'center',
backgroundColor: "blue",
alignItems: 'flex-start'
},
columnStyle: {
flex: 0.7,
flexDirection:'column',
backgroundColor: "red",
borderWidth: 1,
alignItems: 'flex-start'
},
imgStyle: {
flex: 1,
height: undefined,
width: undefined,
alignSelf: 'stretch',
}
})
const Component = props => (
<View style={styles.pageContainer}>
<View style={styles.columnStyle}>
<Image
style={styles.imgStyle}
resizeMode="contain"
source={require('../../../assets/images/onboarding-how-it-works.png')}
/>
</View>
</View>
);
Which gives this:
Centered on page
But if I try to get the image to align top with this code:
imgStyle: {
flex: 1,
height: undefined,
width: undefined,
alignSelf: 'felx-start',
}
I get this (the image has disappeared):
No image
After a bit more investigation I can see that acutally the image is stretching to fit as it has the flex: 1 property. I set the background colour to yellow on the image and get this:
Image background shows size of image box
So the question is, how do I get the image to be responsive without its container stretching to the parent and shrinking to fit the responsive image content, and then align it to the top?

How react native Text and Image responsive? smaller text and image in small device, bigger text and image in large device

How react native Text and Image responsive?
I only know the Flexbox can make layout responsive but seems can not apply in text and image.
e.g.Make my text and image smaller in iphone 4s, bigger in iphone 6
Thanks.
You can use Flexbox in order to make your application responsive.
For example, say you wanted to display a line of text and an image on the same line:
class ResponsiveExample extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>
Example of centered text
</Text>
<Image
resizeMode={"contain"}
style={styles.image}
source={{uri: "your image"}}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
},
text: {
marginLeft: 20,
flex: 1
},
image: {
marginRight: 20,
height: 400,
flex: 3,
}
});
Now the text and image will be displayed relative to the screen size. The usual hangup here is that flexDirection defaults to column, which will make things line up vertically. You can see what happens when we flip from portrait to landscape orientation:
As you can see, the text and image respond to the change in orientation.
For a better overview of Flexbox, I like to refer to the following guide:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/.
Just keep in mind that React Native defaults to a flex-direction of column, so if you want things laid out horizontally, you'll have to explicitly set it to row.
I think react-native-fit-image is useful for you.
React Native Fit Image enables you to draw responsive image component.
You can use this component as below.
<FitImage
source={{ uri: 'http://facebook.github.io/react/img/logo_og.png' }}
style={styles.fitImage}
/>
You are right to think about Flexbox, simply wrap your Text and Image inside View and make those View flexbox responsive.

Resources