How to "stack" touch events in React Native - react-native

I have a feed of items that looks something like this:
What I am trying to Achieve:
When the user presses an item in the feed (represented by the black box), they will be brought to a separate page for that item. When the user clicks on the star icon, they can "favorite" the item.
How I am trying to do it:
I am currently trying to implement this by nesting two TouchableOpacity's (represented by the black boxes), where the inner/child TouchableOpacity has a zIndex: 2 style applied to it.
The zIndex style does not seem to give a priority to the child container for touch events, so I was wondering if anyone knows how I can implement this pattern. I think I might need to use the PanResponder, but it seems like a very verbose way to add this functionality.
Any comments or examples would be greatly appreciated ! Thanks.

Can you not simply nest a TouchableOpacity in your parent TouchableOpacity ? I've done a mock project and this below seems to work
<View>
<TouchableOpacity
style = {{backgroundColor: 'red', height: 100}}
onPress = {() => {console.log("PARENT METHOD")}}>
//content
<TouchableOpacity
style = {{width: 30, height: 30, backgroundColor: 'yellow',
position: 'absolute', right: 5, bottom: 5}}
onPress = {() => {console.log("CHILD METHOD")}}>
//content
</TouchableOpacity>
</TouchableOpacity>
</View>
I've used logs and when pressing the small nested box, only child method is logged, and similarly for if i press the parent view.
Log output: showing independant touches
Let me know if this helps

Why not something like below:
<View style={{flex-direction: "row"}}>
<View>
<TouchableOpacity onPress={this.goToDetails.bind(this)}>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress={this.goToDetails.bind(this)}>
</TouchableOpacity>
<TouchableOpacity onPress={this.favoriteItem.bind(this)}>
</TouchableOpacity>
</View>
</View>
Where you have two views in a row, first view has one TouchableOpacity, and the second view has two TouchableOpacitys in a a column (where first one is similar to previous TouchableOpacity, and the second is to favorite the item).
Should be structured like this:

Related

ScrollView won't Scroll at all

I have a React page that needs a Scrollview, there's no way around it. The content goes off the bottom of the screen, and it is encapsulated in the ScrollView. I have a red border on the ScrollView element so I can see that it goes past the bottom of the screen where the rest of my content it. However, it just does not want to scroll. I even put an 'onScroll' prop inside with console.log('hit') at one point to see if the ScrollView was even registering my attempts, it was not. This is happening in a couple of similar components, their structure is very similar. The smallest of them looks like this...
<ScrollView style={{borderColor: 'red', borderWidth: 3}}>
<View style={QualityStyles.container}>
<View style={{width: '100%'}}>
<Text style={QualityStyles.leadersTitle}>Top Three Leaders</Text>
</View>
<View style={QualityStyles.topThree}>
{renderTopThree(topThree)}
</View>
<View style={{width: '100%'}}>
<Text style={QualityStyles.leadersTitle}>Employees</Text>
</View>
<View style={QualityStyles.remainders}>
{renderOthers(others)}
</View>
</View>
</ScrollView>
The code's pretty straightforward, with renderTopThree returning 3 components that will take up about 90% of the screen, and renderOthers will fit maybe one component on the screen, and the rest (while rendered and existent) can't be seen since I can't scroll. Anyone see what could be wrong?
I resolved the issue, I had a TouchableWithoutFeedback wrappping the entire Application, and it was blocking out any ability to scroll

React Native | Default Set Width Style

I noticed that while adding 'View' with React native, it behaves as if "width: '100%'" was assigned even though I did not enter any style. Same situation exists for any component. It covers the whole area horizontally. What is the cause and solution?
return (
<View style={{flex:1}}>
{/* paints the line he is in full red but should only paint as much as the line of the text */}
<View style={{backgroundColor:'red'}}>
<Text>Example</Text>
</View >
</View>
);
If you want the background color to only encompass the text, you can use this:
<Text style={{backgroundColor: 'red', alignSelf: 'flex-start'}}>
Example
</Text>

Touchable Opacity onPressIn color change

I have the following code in my RN application.
<TouchableOpacity
// onPress={onPress}
onPressIn={this.handlePressIn}
onPressOut={this.handlePressOut}
disabled={disabled}
style={[
styles.button,
buttonStyle,
this.buttonStyles(),
]}
>
<Text>Hello</Text>
</TouchableOpacity>
I want to change the color of TouchableOpacity when it is being pressed. So, in onPressIn, I changed the color to darkRed, but it display a light red or something similar to that. No dark color can be set there. What is the issue here? How can I change the color till I onPressOut? The color should be a dark one.
Found the solution. Set your activeOpacity={1} in your TouchableOpacity.
<TouchableOpacity
onPress={onPress}
activeOpacity={1}
/>
Edit:
I guess I overengineered it a little bit. You can simply use the activeOpacity={1} prop.
Problem:
The problem is that TouchableOpacity already provides feedback by reducing the opacity of the button, allowing the background to be seen through while the user is pressing down. So even if you change the backgroundcolor of the button, you won't notice it. Fortunately, I have a solution for you.
Solution:
You can use TouchableWithoutFeedback together with an additional View to create your wanted behavior.
Code:
<TouchableWithoutFeedback
onPressIn={() => this.setState({pressIn: true })}
onPressOut={() => this.setState({pressIn: false})}
>
<View
// change the color depending on state
style={{ backgroundColor: this.state.pressIn ? '#4c7d4c': '#98FB98'}}
>
<Text> Custom Button </Text>
</View>
</TouchableWithoutFeedback>
Output:
Working Example:
https://snack.expo.io/#tim1717/quiet-watermelon

Style breaks when using TouchableOpacity instead of TouchableWithoutFeedback

Here's how this part looks using TouchableWithoutFeedback
And here is the same thing, except with TouchableOpacity
The code for this part:
<TouchableWithoutFeedback>
<View style={styles.buyCoinsItem}>
<View style={styles.cost}>
<Text>{no_of_coins}</Text>
</View>
<Text>{product.priceString}</Text>
<View style={{height:30, flexDirection: 'row', marginTop:10}}>
{displayDiscount &&
<View style={styles.discountContainer}>
<Text style={styles.whiteText}>Save {discount}</Text>
</View>
}
</View>
</View>
</TouchableWithoutFeedback>
What's going on here?
This is an annoying side effect of how the two components are implemented.
Essentially, TouchableOpacity is a native-backed View that supports touch interactions by calling setNativeProps({ opacity }) on that view, whereas TouchableWithoutFeedback is simply wraps a native view and attaches the touch handlers.
In order to make TouchableWithoutFeedback behave like TouchableOpacity, nest an additional View inside it, and define any styles on the child view:
Before:
<TouchableOpacity onPress={...} style={styles.touchable}>
// Touchable content
</TouchableOpacity>
After:
<TouchableWithoutFeedback onPress={...}>
<View style={styles.touchable}>
// Touchable content
</View>
</TouchableWithoutFeedback>
I'm not sure why the API was designed this way - my guess would be to avoid creating an additional native backing view for performance reasons when it's not needed.
However, from refactoring purposes, this makes it slightly more painful to move between different types of Touchables. In my projects, I typically create a custom Touchable component that wraps this logic behind a prop, or use something like react-native-platform-touchable, which gives you Android Material-style effects on Android.
Nvm, I figured it out. I basically switched the TouchableOpacity with the outer View. So, like this:
<View style={styles.buyCoinsItem}>
<TouchableOpacity>
<View style={styles.cost}>
<Text>{no_of_coins}</Text>
</View>
<Text>{product.priceString}</Text>
<View style={{height:30, flexDirection: 'row', marginTop:10}}>
{displayDiscount &&
<View style={styles.discountContainer}>
<Text style={styles.whiteText}>Save {discount}</Text>
</View>
}
</View>
</TouchableOpacity>
</View>

React Native - How do you create a vertical overlay?

I was just wondering if it was possible, in React Native, to create a vertical overlay ; by that, I mean being on a page and when swiping down, an overlay comes down, covering the page, with various information on it (and the same when swiping up, an overlay coming from the bottom). I wanted to use react-native-swiper at first, but the vertical swiping is not compatible with Android.. So if anyone has another solution to offer, be my guest ! Thanks
check react-native-parallax-view hope this can help you.
EDIT
example:
return (
<View style={[{ flex: 1 }]}> {/* add parent container and then ParallaxView as specified in documentation */}
<ParallaxView
backgroundSource={require('image!backgroundImage')}
windowHeight={300}
header={(
<Text style={styles.header}>
Header Content
</Text>
)}
scrollableViewStyle={{ backgroundColor: 'red' }}
>
<View>
// ... scrollview content
</View>
</ParallaxView>
</View>
);