Events and Gestures

Back

Loading concept...

User Interaction in React Native: Events and Gestures

The Story of Your App’s Conversation

Imagine your app is like a friendly robot that wants to understand what you’re doing. When you tap, swipe, or type, you’re talking to it. The robot needs special ears (called event handlers) to listen and respond to you!


What is Event Handling?

Think of event handling like a doorbell. When someone presses the bell (the event), the sound plays (the response). Your app works the same way!

Simple Example: The Button Tap

<Button
  title="Say Hello"
  onPress={() => console.log('Hello!')}
/>

When you tap the button, it says “Hello!” Simple, right?

The Event Object

Every time something happens, your app gets a little note with details about what happened. This note is called an event object.

onPress={(event) => {
  console.log('You tapped at:',
    event.nativeEvent.locationX);
}}

The note tells you where you tapped, when it happened, and more!


Touch Events: The Five Ways to Touch

Your phone understands five different ways you can touch it. Think of them like five different handshakes!

graph TD A["Touch Events"] --> B["TouchableOpacity"] A --> C["TouchableHighlight"] A --> D["TouchableWithoutFeedback"] A --> E["Pressable"] A --> F["TouchableNativeFeedback"] B --> B1["Fades when pressed"] C --> C1["Lights up when pressed"] D --> D1["No visual change"] E --> E1["Modern &amp; flexible"] F --> F1["Android ripple"]

TouchableOpacity: The Fading Button

When you press it, it becomes a little see-through. Like a ghost!

<TouchableOpacity
  onPress={() => alert('Tapped!')}
  activeOpacity={0.5}
>
  <Text>Press Me</Text>
</TouchableOpacity>

TouchableHighlight: The Glowing Button

When you press it, a color appears underneath. Like magic!

<TouchableHighlight
  onPress={() => alert('Pressed!')}
  underlayColor="#DDDDDD"
>
  <Text>Press Me</Text>
</TouchableHighlight>

TouchableWithoutFeedback: The Invisible Listener

It listens but doesn’t show any change. Perfect for hiding secret taps!

<TouchableWithoutFeedback
  onPress={() => console.log('Secret tap!')}
>
  <View style={styles.box} />
</TouchableWithoutFeedback>

Pressable: The Modern Hero

The newest and most powerful! It can do everything.

<Pressable
  onPress={() => console.log('Pressed!')}
  onPressIn={() => console.log('Finger down')}
  onPressOut={() => console.log('Finger up')}
  onLongPress={() => console.log('Long press!')}
>
  <Text>Super Button</Text>
</Pressable>

TouchableNativeFeedback: The Android Special

Only for Android! Shows a beautiful ripple effect.

<TouchableNativeFeedback
  onPress={() => console.log('Ripple!')}
  background={TouchableNativeFeedback
    .Ripple('#000', false)}
>
  <View style={styles.button}>
    <Text>Android Button</Text>
  </View>
</TouchableNativeFeedback>

Gesture Responder System: Who’s in Charge?

Imagine many kids all want to play with the same toy. The Gesture Responder System decides who gets to play!

The Four Big Questions

When you touch the screen, your app asks:

graph TD A["Touch Starts"] --> B{Can I be the responder?} B -->|Yes| C["onStartShouldSetResponder"] B -->|Moving?| D["onMoveShouldSetResponder"] C --> E[I'm in control!] D --> E E --> F["onResponderGrant"] E --> G["onResponderMove"] E --> H["onResponderRelease"]

The Simple Version

<View
  onStartShouldSetResponder={() => true}
  onResponderGrant={() =>
    console.log('I got control!')}
  onResponderMove={() =>
    console.log('Moving...')}
  onResponderRelease={() =>
    console.log('Touch ended!')}
>
  <Text>Touch me!</Text>
</View>

Why This Matters

If you have a scrolling list inside a swipeable card, who should move? The list or the card? The Gesture Responder System figures this out!


PanResponder: The Movement Master

PanResponder is like teaching your robot to follow your finger. It’s perfect for dragging things around!

Think of It Like a Puppet

Your finger is the puppet master. The element on screen is the puppet. PanResponder is the strings connecting them!

Building a Draggable Box

const pan = useRef(
  new Animated.ValueXY()
).current;

const panResponder = useRef(
  PanResponder.create({
    onStartShouldSetPanResponder:
      () => true,
    onPanResponderMove:
      Animated.event(
        [null, {dx: pan.x, dy: pan.y}],
        {useNativeDriver: false}
      ),
    onPanResponderRelease: () => {
      Animated.spring(pan, {
        toValue: {x: 0, y: 0},
        useNativeDriver: false
      }).start();
    }
  })
).current;

Using the Draggable Box

<Animated.View
  style={{
    transform: [
      {translateX: pan.x},
      {translateY: pan.y}
    ]
  }}
  {...panResponder.panHandlers}
>
  <Text>Drag Me!</Text>
</Animated.View>

PanResponder Events Explained

Event What It Means
dx How far moved left/right
dy How far moved up/down
vx Speed going left/right
vy Speed going up/down
x0 Where touch started (X)
y0 Where touch started (Y)

Keyboard Events: When You Type

When the keyboard pops up, your app needs to know! Otherwise, the keyboard might cover important stuff.

The Problem

Imagine you’re filling out a form. You tap the last field, the keyboard appears… and now you can’t see what you’re typing!

The Solution: KeyboardAvoidingView

<KeyboardAvoidingView
  behavior={Platform.OS === 'ios'
    ? 'padding'
    : 'height'}
  style={{flex: 1}}
>
  <TextInput
    placeholder="Type here..."
    style={styles.input}
  />
  <Button title="Submit" />
</KeyboardAvoidingView>

Keyboard Show and Hide Events

Your app can listen for when the keyboard appears or disappears.

useEffect(() => {
  const showListener =
    Keyboard.addListener(
      'keyboardDidShow',
      () => console.log('Keyboard up!')
    );

  const hideListener =
    Keyboard.addListener(
      'keyboardDidHide',
      () => console.log('Keyboard gone!')
    );

  return () => {
    showListener.remove();
    hideListener.remove();
  };
}, []);

Keyboard API: Your Keyboard Remote Control

The Keyboard API is like a TV remote for your keyboard. You can make it appear, disappear, and more!

Dismiss the Keyboard

When you tap outside a text field, hide the keyboard:

<TouchableWithoutFeedback
  onPress={Keyboard.dismiss}
>
  <View style={styles.container}>
    <TextInput placeholder="Tap outside" />
  </View>
</TouchableWithoutFeedback>

All Keyboard Events

graph TD A["Keyboard API"] --> B["keyboardWillShow"] A --> C["keyboardDidShow"] A --> D["keyboardWillHide"] A --> E["keyboardDidHide"] A --> F["keyboardWillChangeFrame"] A --> G["keyboardDidChangeFrame"] B --> B1["iOS only - Before show"] C --> C1["After fully shown"] D --> D1["iOS only - Before hide"] E --> E1["After fully hidden"]

Getting Keyboard Height

Sometimes you need to know how tall the keyboard is:

Keyboard.addListener(
  'keyboardDidShow',
  (e) => {
    const height =
      e.endCoordinates.height;
    console.log('Keyboard is',
      height, 'pixels tall');
  }
);

Quick Reference: When to Use What?

I Want To… Use This!
Simple button tap onPress
Button with fade effect TouchableOpacity
Drag something PanResponder
Handle complex touches Gesture Responder
Hide keyboard on tap outside Keyboard.dismiss
Move content when keyboard shows KeyboardAvoidingView

The Big Picture

graph TD A["User Touches Screen"] --> B{What type?} B --> C["Single Tap"] B --> D["Drag/Swipe"] B --> E["Type on Keyboard"] C --> C1["Touch Events"] C1 --> C2["Pressable/Touchable"] D --> D1["Gesture System"] D1 --> D2["PanResponder"] E --> E1["Keyboard API"] E1 --> E2["KeyboardAvoidingView"]

You Did It!

You now understand how your app listens to users! Remember:

  • Touch Events = Simple taps and presses
  • Gesture Responder = Who handles the touch
  • PanResponder = Dragging and complex gestures
  • Keyboard Events = When typing starts/stops
  • Keyboard API = Control the keyboard

Your app is no longer just a screen. It’s a conversation partner that listens and responds to every touch, swipe, and keystroke!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.