The soft keyboard covers roughly the bottom 40% of the screen. KeyboardAvoidingView adjusts itself by the overlap as behavior says: 'padding' adds bottom padding, 'height' shrinks the view, and 'position' moves a content container. keyboardVerticalOffset subtracts anything above the view, such as a navigation header. The Keyboard module closes the keyboard (Keyboard.dismiss()) and reports its size.
useEffect(() => {
const sub = Keyboard.addListener('keyboardDidShow', (e) =>
console.log('keyboard height:', e.endCoordinates.height));
return () => sub.remove();
}, []);
return (
<Screen>
<KeyboardAvoidingView style={{ flex: 1 }} behavior="padding" enabled>
<Pressable style={{ flex: 1, gap: 12 }} accessible={false} onPress={Keyboard.dismiss}>
<Text style={[ui.h1, { flex: 1 }]}>Ask the bookseller</Text>
<TextInput style={ui.input} placeholder="Your question" />
<View style={ui.button}><Text style={ui.buttonText}>Send</Text></View>
</Pressable>
</KeyboardAvoidingView>
</Screen>Tapping the field opened the keyboard, and Metro printed the listener's report in density-independent pixels:
LOG keyboard height: 312.3809509277344
With enabled={false} the keyboard covered the field and the Send button; enabled, they sat on top of it, as the composer does in the figure in Reading Notes Screen. The Pressable wrapper (with accessible={false}, so screen readers do not see one giant button) dismisses the keyboard on a tap in empty space. behavior="padding" works on Android 16 because edge-to-edge drawing is enforced there, so the window no longer resizes for the keyboard; Expo 6,418 's guide still suggests leaving behavior undefined on Android for older setups. For long forms, react-native-keyboard-controller 3,738 (github.com/kirillzyusko/react-native-keyboard-controller (https://github.com/kirillzyusko/react-native-keyboard-controller 3,738 )) scrolls the focused field into view; it needs Reanimated 11,010 and a development build.