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)
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.
removeAllListeners()
Removes all listeners for a specific event type.
Keyboard.removeAllListeners(eventType);
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);
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>
);
};
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