React Native - How to add opacity feedback to Pressable component?

Viewed 2138

The new Pressable component is great; I like being able to access new events but, how do you add the opacity feedback the TouchableOpacity component has?

4 Answers

Given the answer of @Adams:

Here is the code, which worked for me. You can customize it.

import React from "react";
import { Pressable, Animated } from "react-native";

const animated = new Animated.Value(1);
const PressableOpacity = ({ children, ...props }) => {
  const fadeIn = () => {
    Animated.timing(animated, {
      toValue: 0.1,
      duration: 100,
      useNativeDriver: true,
    }).start();
  };
  const fadeOut = () => {
    Animated.timing(animated, {
      toValue: 1,
      duration: 200,
      useNativeDriver: true,
    }).start();
  };

  return (
    <Pressable onPressIn={fadeIn} onPressOut={fadeOut} {...props}>
      <Animated.View style={{ opacity: animated }}>{children}</Animated.View>
    </Pressable>
  );
};

export default PressableOpacity;

You shoud use Animated API: https://reactnative.dev/docs/animated .
There is even an example with opacity. You can also rewrite the example so that the button changes the opacity after "Press in" and returns to the default value after "Press Out"

You can also use React Native ReAnimated 2 if you want a better version of @Andre's answer.

import Animated, {EasingNode} from 'react-native-reanimated';

const AnimatedView = Animated.View;
const animatedOpacity = new Animated.Value(1);

function fadeIn() {
  return Animated.timing(animatedOpacity, {
    toValue: 0.7,
    duration: 100,
    easing: EasingNode.inOut(EasingNode.ease),
  }).start();
}

function fadeOut() {
    return Animated.timing(animatedOpacity, {
    toValue: 1,
    duration: 120,
    easing: EasingNode.inOut(EasingNode.ease),
  }).start();
}

........
........

return(
    <Pressable
      onPressIn={fadeIn}
      onPressOut={fadeOut}
      onPress={() => console.log("Pressed !)}>
        <AnimatedView 
          style={[styles.button, {opacity: animatedOpacity}]}>
          <Text>Click Me!<Text>
        </AnimatedView>
    </Pressable>
 );

There's a simple solution given here: https://medium.com/timeless/a-simple-touch-feedback-with-the-new-pressable-component-b4d91c35456

The style parameter of the Pressable component accepts function with pressed boolean which is very handy for this case.

I've made a simple cover component not to change the code:


import { Pressable as PressableRaw } from 'react-native';

function Pressable(props) {
    return <PressableRaw
            onPress={props.onPress}
            hitSlop={props.hitSlop}
            style={({ pressed }) => [props.style || {}, {opacity:pressed ? 0.5 : 1}]}
            >{props.children}</PressableRaw>
}
Related