Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 605
BoredBurrito Avatar asked Jan 08 '18 18:01

BoredBurrito


2 Answers

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.

like image 91
jevakallio Avatar answered Sep 27 '22 22:09

jevakallio


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>
like image 22
BoredBurrito Avatar answered Sep 27 '22 22:09

BoredBurrito