Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/facebook/react-native/llms.txt

Use this file to discover all available pages before exploring further.

The Keyboard module allows you to listen for native keyboard events and control the keyboard’s behavior, such as dismissing it programmatically.

Import

import { Keyboard } from 'react-native';

Methods

addListener()

Connects a JavaScript function to a keyboard event.
const subscription = Keyboard.addListener(eventType, listener);
eventType
KeyboardEventName
required
The keyboard event to listen for:
  • 'keyboardWillShow': Keyboard will appear (iOS only)
  • 'keyboardDidShow': Keyboard has appeared
  • 'keyboardWillHide': Keyboard will hide (iOS only)
  • 'keyboardDidHide': Keyboard has hidden
  • 'keyboardWillChangeFrame': Keyboard frame will change (iOS only)
  • 'keyboardDidChangeFrame': Keyboard frame changed (iOS only)
listener
function
required
Callback function invoked when the event fires. Receives a KeyboardEvent object.
Returns: EventSubscription - Object with a remove() method to unsubscribe.

dismiss()

Dismisses the active keyboard and removes focus from any focused input.
Keyboard.dismiss();

removeAllListeners()

Removes all listeners for a specific event type.
Keyboard.removeAllListeners(eventType);
eventType
KeyboardEventName
The event type to remove listeners for. If not provided, removes all listeners.

isVisible()

Returns whether the keyboard is currently visible.
const visible = Keyboard.isVisible();
Returns: boolean

metrics()

Returns the current keyboard metrics if the keyboard is visible.
const metrics = Keyboard.metrics();
Returns: KeyboardMetrics | null - Object with screenX, screenY, width, and height, or null if keyboard is hidden.

scheduleLayoutAnimation()

Synchronizes layout animations with keyboard movements.
Keyboard.scheduleLayoutAnimation(event);
event
KeyboardEvent
required
The keyboard event object received from a listener.

Types

KeyboardEvent

type KeyboardEvent = {
  duration: number;          // Animation duration in ms
  easing: KeyboardEventEasing;
  endCoordinates: KeyboardMetrics;
  startCoordinates?: KeyboardMetrics; // iOS only
  isEventFromThisApp?: boolean;       // iOS only
};

KeyboardMetrics

type KeyboardMetrics = {
  screenX: number;  // X position on screen
  screenY: number;  // Y position on screen
  width: number;    // Keyboard width
  height: number;   // Keyboard height
};

KeyboardEventEasing

type KeyboardEventEasing =
  | 'easeIn'
  | 'easeInEaseOut'
  | 'easeOut'
  | 'linear'
  | 'keyboard';

Examples

Basic Keyboard Dismissal

import React from 'react';
import {
  View,
  TextInput,
  Button,
  Keyboard,
  StyleSheet,
} from 'react-native';

const KeyboardDismissExample = () => {
  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        placeholder="Type here..."
      />
      <Button
        title="Dismiss Keyboard"
        onPress={() => Keyboard.dismiss()}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  input: {
    height: 40,
    borderWidth: 1,
    padding: 10,
    marginBottom: 20,
  },
});

Listening to Keyboard Events

import React, { useEffect, useState } from 'react';
import { View, Text, Keyboard } from 'react-native';

const KeyboardListener = () => {
  const [keyboardStatus, setKeyboardStatus] = useState('hidden');
  const [keyboardHeight, setKeyboardHeight] = useState(0);

  useEffect(() => {
    const showSubscription = Keyboard.addListener('keyboardDidShow', (e) => {
      setKeyboardStatus('shown');
      setKeyboardHeight(e.endCoordinates.height);
    });

    const hideSubscription = Keyboard.addListener('keyboardDidHide', () => {
      setKeyboardStatus('hidden');
      setKeyboardHeight(0);
    });

    return () => {
      showSubscription.remove();
      hideSubscription.remove();
    };
  }, []);

  return (
    <View>
      <Text>Keyboard Status: {keyboardStatus}</Text>
      <Text>Keyboard Height: {keyboardHeight}</Text>
    </View>
  );
};

Animated Content Shift

import React, { useEffect, useRef } from 'react';
import {
  View,
  TextInput,
  Animated,
  Keyboard,
  StyleSheet,
} from 'react-native';

const AnimatedKeyboardExample = () => {
  const offsetY = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    const keyboardWillShow = Keyboard.addListener(
      'keyboardWillShow',
      (e) => {
        Animated.timing(offsetY, {
          toValue: -e.endCoordinates.height / 2,
          duration: e.duration,
          useNativeDriver: true,
        }).start();
      },
    );

    const keyboardWillHide = Keyboard.addListener(
      'keyboardWillHide',
      (e) => {
        Animated.timing(offsetY, {
          toValue: 0,
          duration: e.duration,
          useNativeDriver: true,
        }).start();
      },
    );

    return () => {
      keyboardWillShow.remove();
      keyboardWillHide.remove();
    };
  }, [offsetY]);

  return (
    <Animated.View
      style={[
        styles.container,
        { transform: [{ translateY: offsetY }] },
      ]}
    >
      <TextInput
        style={styles.input}
        placeholder="Type here..."
      />
    </Animated.View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
  input: {
    height: 40,
    borderWidth: 1,
    padding: 10,
  },
});

Using scheduleLayoutAnimation

import React, { useEffect } from 'react';
import {
  View,
  TextInput,
  Keyboard,
  LayoutAnimation,
  StyleSheet,
} from 'react-native';

const LayoutAnimationExample = () => {
  useEffect(() => {
    const keyboardWillShow = Keyboard.addListener(
      'keyboardWillShow',
      (e) => {
        Keyboard.scheduleLayoutAnimation(e);
      },
    );

    const keyboardWillHide = Keyboard.addListener(
      'keyboardWillHide',
      (e) => {
        Keyboard.scheduleLayoutAnimation(e);
      },
    );

    return () => {
      keyboardWillShow.remove();
      keyboardWillHide.remove();
    };
  }, []);

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        placeholder="Type here..."
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'flex-end',
    padding: 20,
  },
  input: {
    height: 40,
    borderWidth: 1,
    padding: 10,
  },
});

Dismiss on Tap Outside

import React from 'react';
import {
  View,
  TextInput,
  TouchableWithoutFeedback,
  Keyboard,
  StyleSheet,
} from 'react-native';

const DismissKeyboardHOC = ({ children }) => (
  <TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
    {children}
  </TouchableWithoutFeedback>
);

const FormScreen = () => {
  return (
    <DismissKeyboardHOC>
      <View style={styles.container}>
        <TextInput
          style={styles.input}
          placeholder="Name"
        />
        <TextInput
          style={styles.input}
          placeholder="Email"
        />
      </View>
    </DismissKeyboardHOC>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  input: {
    height: 40,
    borderWidth: 1,
    padding: 10,
    marginBottom: 20,
  },
});

Custom Hook for Keyboard State

import { useEffect, useState } from 'react';
import { Keyboard } from 'react-native';

const useKeyboard = () => {
  const [keyboardHeight, setKeyboardHeight] = useState(0);
  const [isKeyboardVisible, setIsKeyboardVisible] = useState(false);

  useEffect(() => {
    const showSubscription = Keyboard.addListener('keyboardDidShow', (e) => {
      setKeyboardHeight(e.endCoordinates.height);
      setIsKeyboardVisible(true);
    });

    const hideSubscription = Keyboard.addListener('keyboardDidHide', () => {
      setKeyboardHeight(0);
      setIsKeyboardVisible(false);
    });

    return () => {
      showSubscription.remove();
      hideSubscription.remove();
    };
  }, []);

  return { keyboardHeight, isKeyboardVisible };
};

// Usage
const MyComponent = () => {
  const { keyboardHeight, isKeyboardVisible } = useKeyboard();

  return (
    <View style={{ paddingBottom: keyboardHeight }}>
      {/* Your content */}
    </View>
  );
};

Platform Differences

iOS

  • Supports keyboardWillShow, keyboardWillHide, keyboardWillChangeFrame events
  • Provides smooth animation curves with easing and duration
  • Includes startCoordinates in event data
  • Keyboard appearance can be customized per input

Android

  • Only supports keyboardDidShow and keyboardDidHide events
  • No keyboardWill* events (no pre-animation callbacks)
  • Keyboard behavior depends on android:windowSoftInputMode setting
  • Requires adjustResize or adjustPan mode for layout events on API < 30
// Platform-specific event handling
import { Platform } from 'react-native';

const eventType = Platform.select({
  ios: 'keyboardWillShow',
  android: 'keyboardDidShow',
});

const subscription = Keyboard.addListener(eventType, handler);

KeyboardAvoidingView

For automatic keyboard avoidance, use KeyboardAvoidingView component:
import { KeyboardAvoidingView, Platform } from 'react-native';

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

Best Practices

Use keyboardWillShow on iOS and keyboardDidShow on Android for cross-platform compatibility:
const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
Always remove event listeners in cleanup functions to prevent memory leaks.
On Android, keyboard events may not fire if android:windowSoftInputMode is set to adjustNothing in AndroidManifest.xml.

Common Use Cases

  • Adjust layout: Move content up when keyboard appears
  • Form validation: Submit form when keyboard is dismissed
  • Chat interfaces: Scroll to bottom when keyboard shows
  • Floating buttons: Reposition buttons above keyboard
  • Custom keyboard accessories: Add custom toolbars above keyboard

Build docs developers (and LLMs) love